Home > OS >  How to return a union from the fn
How to return a union from the fn

Time:01-27

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 | number is 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> 

https://www.typescriptlang.org/play?ssl=14&ssc=1&pln=1&pc=1#code/C4TwDgpgBAChBOBnA9gOygXigbwFBQKlQEMBbCALikWHgEtUBzAGn0OMcqIFdSAjBLgC uXKEhQAasQA23CAHkAZgB4AKgD5MUNQG0A1hBDIlOgLoBuUeOgANbdLmLVcJGg2iAxmhpQl6LAAKUhBHeSow5xVXFFQNAEoI2XllaIRYrQwtPEIoeAhgbnh0EMjhUSA

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:

TS Playground

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) */
  •  Tags:  
  • Related