Necesito hacer que esta lógica funcione.
const defaultNumberOption = { label: 'Select', value: 0, }; const defaultStringOption = { label: 'Select', value: '', }; const getDefaultOption = <ValueType extends string | number>(): IOption => { // if ValueType is 'string' - return defaultStringOption // if ValueType is 'number' - return defaultNumberOption }Traté de usar diferentes enfoques, pero con cada uno de ellos tenía el mismo problema: no puedo encontrar la manera de hacer una estructura con tipos en condición, pero con valores en expresión.
Si hay una manera de hacerlo, sería genial.
enum FixedLabel {Select} const defaultNumberOption = { label: FixedLabel.Select, value: 0, }; const defaultStringOption = { label: FixedLabel.Select, value: '', }; type DefaultNumber = { label: FixedLabel, value: number}; type DefaultString = { label: FixedLabel, value: string}; type IOption = DefaultNumber | DefaultString; const getDefaultOption = (v : number | string): IOption => { // if ValueType is 'string' - return defaultStringOption // if ValueType is 'number' - return defaultNumberOption if(typeof v === 'string'){ return defaultNumberOption; } else { return defaultStringOption; } }Puede intentar que esto funcione, ya que también puede usar una cadena en lugar de una enumeración si no es específico para las etiquetas.
Podría usar tipos condicionales para lograr esto.
interface DefaultNumberOption { label: 'Select', value: number, } interface DefaultStringOption { label: 'Select', value: string, } type DefaultOption<T extends number | string> = T extends string ? DefaultStringOption : DefaultNumberOption const getDefaultOption = <T extends number | string>(value: T): DefaultOption<T> => { if (typeof value === 'string') { return { label: 'Select', value: '' } as DefaultOption<T>; } return { label: 'Select', value: 0 } as DefaultOption<T>; } let x = getDefaultOption(''); // x will have type DefaultStringOption let y = getDefaultOption(0); // y will have type DefaultNumberOptionAquí hay un enlace a un patio de juegos de TS si quiere jugar con la solución.
TypeScript pierde la información de escritura proporcionada en <T extends string | number> al compilar en JS, por lo que no le permite usar eso.
Para obtener el tipo, es posible que desee proporcionarlo como un parámetro en la función.
const getDefaultOption = <T extends string | number>(optionValue: T): IOption => { return typeof optionValue === "string" ? defaultStringOption : defaultNumberOption; }También es posible agregarlo al tipo de devolución en su lugar:
const getDefaultOption = <T extends string | number>(getOptionType: T): IOption<string | number> => { if (typeof getOptionType === "string") return defaultStringOption; else return defaultNumberOption; } Tenga en cuenta que IOption no puede contener <T> ya que TS requeriría que el tipo de valor devuelto fuera string | number en lugar de string o number .
Aquí está mi patio de juegos TS