First a function implementation with only conditional types that works
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabel;
type createLabelType = <T extends number | string>(idOrName: T) => NameOrId<T>;
const createLabel: createLabelType = idOrName => {
if (typeof idOrName === 'number') return { id: idOrName } as NameOrId<typeof idOrName>;
return { name: idOrName } as NameOrId<typeof idOrName>;
};
const nameLable = createLabel('str'); // nameLable has NameLabel type
const idLable = createLabel(1); // idLable has IdLabel type
how to do something similar based on optional id parameter? is it possible?
/** expample 2. HOW TO FORCE IT WORKS? */
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
type NameOrId<T extends number | undefined> = T extends number ? IdLabel : NameLabel;
type createLabelType = <T extends number | undefined>(id?: T) => NameOrId<T>;
const createLabel: createLabelType = id => {
// *
if (typeof id === 'number') return ({ id } as unknown) as NameOrId<typeof id>;
return { name: id } as NameOrId<typeof id>;
};
const nameLable = createLabel(); // nameLable has IdLabel type, but I want to see NameLabel
const idLable = createLabel(1); // idLable has IdLabel type
without to cast unknown type
Conversion of type '{ id: T; }' to type 'NameOrId<T>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.ts(2352)
typescript version "4.2.4" strictNullChecks false