I the following, X as union type string | number which is correct.
The fn instead has a return type ValueOf<Person>.
I would like to ask you:
- why a union like
string | numberis not returned? - how to make sure the return the union based on the value of
ValueOf<Person>?
Thanks
type Person = {
name: string,
age: number
}
type ValueOf<T> = T[keyof T];
type X = ValueOf<Person> // string | number >>> OK
const fn = (myValue: ValueOf<Person>): ValueOf<Person> => {
return myValue
} // fn is ValueOf<Person>
CodePudding user response:
You can get an even more narrow type than just "any type in the union" by using a generic type parameter with your function:
type Person = {
name: string;
age: number;
favoriteNumbers: number[];
};
type ValueOf<T> = T[keyof T];
function identity <T extends ValueOf<Person>>(value: T): T {
return value;
}
const result1 = identity('hello'); // "hello"
result1.toUpperCase(); // Ok, but this would be an error if it were (string | number | number[])
const result2 = identity(10); // 10
result2.toFixed(3); // Ok, but this would be an error if it were (string | number | number[])
const result3 = identity([1, 5, 7]); // number[]
result3.reverse(); // Ok, but this would be an error if it were (string | number | number[])
// Some types which aren't assignable to ValueOf<Person>:
identity(false); /*
^^^^^
Argument of type 'boolean' is not assignable to parameter of type 'ValueOf<Person>'.(2345) */
identity(['hello']); /*
^^^^^^^
Type 'string' is not assignable to type 'number'.(2322) */
