Home > Enterprise >  Recognised the type
Recognised the type

Time:09-07

I want to get the default option from a list of options.

type
export type Unpacked<T> = T extends Array<infer U> ? U : T;

interface
getDefaultValue?: <T extends Option[]>(options: T) => Unpacked<T>;

Example

const options = [
   {label: "New York", value: 38 }, 
   {label: "Washington", value: 39 }
]
then return type of getDefaultValue must be 38 | 39

Incorrect test is

getDefaultValue={(options: Option[]) => any string}

But I have got error Type 'string' is not assignable to type 'Unpacked<T>'.

UPD

https://codesandbox.io/s/inspiring-galileo-ndto7l?file=/src/App.tsx

export type Unpacked<T> = T extends Array<infer U> ? U : T;

type Option = { label: string; id: number };

const getValues = <T extends Option[]>(anyOptions: T): Unpacked<T> => {
  return anyOptions[0].id;
};

const options: Option[] = [
  { label: "New York", id: 38 },
  { label: "Washington", id: 39 }
];

/** result must be any id from options.*/
/** In current case type of result must be 38 | 39 */
const result = getValues(options);

export default function App() {
  return null;
}

CodePudding user response:

You need to use different approach:

type Option = { label: string; id: number };

const getValues = <
    Id extends number,
    Item extends Option & { id: Id },
    List extends Item[]
>(anyOptions: [...List]): List[number]['id'] => anyOptions[0].id;

// 38 | 39
const result = getValues([
    { label: "New York", id: 38 },
    { label: "Washington", id: 39 }
]);

Playground

You need to infer literal type of id property. More information about function arguments inference you can find in my article

Also, if you have an array and you want to infer elements, you need to use variadic tuple types

  • Related