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 }
]);
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