Describe a scenario where an object contains both getter and setter methods with different types. How can we determine the type of the setter function?
Consider defining an object with getter and setter functions like the example below:
type Foo = {
get bar(): number;
set bar(value: number | string);
}
In this setup, it's straightforward to retrieve the type of the getter method. However, determining the type of the setter poses a challenge.
type Bar = Foo["bar"]; // This will return 'number'
Is there a way to ascertain the type of the setter, such as 'number' or 'string' in the given example?
I've made an attempt at a solution without success.
type SetterType<T, U extends string> = T extends { set [key in U]: infer P } ? P : never;
type Bar = SetterType<Foo, "bar">;
Implementation Applications:
Let's suppose we have an API structured as follows:
const foo = addFoo(); // The function addFoo returns type Foo.
foo.bar = 123;
foo.bar = "123"; // Setting the property works correctly with varying types.
foo.baz = true;
// additional properties...
We aim to wrap this functionality by representing these attributes using a literal object.
This wrapping mechanism will leverage Object.assign
internally.
function myAddFoo(properties: Partial<Foo>): Foo {
const foo = addFoo();
Object.assign(foo, properties);
return foo;
}
const foo = myAddFoo({
bar: "123", // Error - 'bar' must be of type number or undefined.
baz: true,
// other properties...
});
The 'bar' property within the literal object cannot accept values conforming to the setter type 'number | string
'. To resolve this, the function arguments should accommodate the setter type.
type FooSetters = /* Infer all setters type, e.g., `{ bar: number | string }` */;
function myAddFoo(properties: Partial<Omit<Foo, keyof FooSetters> & FooSetters>): Foo