I was looking at the typescript docs and landed on this page on conditional types.
I was trying to implement the createLabel
function in this way:
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
type NameOrId<T extends number | string> = T extends number
? IdLabel
: NameLabel;
function createLabel<T extends number | string>(nameOrId: T): NameOrId<T> {
const label: NameOrId<T> = (typeof nameOrId === 'number') ? { id: nameOrId }: { name: nameOrId} ;
return label;
}
Unfortunately I get an error on the label
creation
Type '{ id: number; } | { name: string; }' is not assignable to type 'NameOrId<T>'.
Type '{ id: number; }' is not assignable to type 'NameOrId<T>'.
What am I doing wrong?
The issue with the code is that TypeScript is unable to infer the correct type of the returned value from the createLabel function. To fix this, you can use a type assertion to explicitly tell TypeScript what the type of the returned value should be.
Here's the corrected code:
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
type NameOrId<T extends number | string> = T extends number
? IdLabel
: NameLabel;
function createLabel<T extends number | string>(nameOrId: T): NameOrId<T> {
return typeof nameOrId === "number"
? { id: nameOrId } as NameOrId<T>
: { name: nameOrId } as NameOrId<T>;
}
const Name = createLabel("5"); // Type is NameLabel
const Id = createLabel(5); // Type is IdLabel