如何从可能未定义的变量和类型参数中获取类型信息



我想根据传入变量val的类型设置一个默认值defVal。很多时候val是未定义的,所以我不能使用JavaScripttypeof运算符。所以T仍然是类型信息的唯一来源。当然,问题是T在运行时是未知的。

CCD_ 7应当是例如"0"表示字符串,0表示数字等。。。类似defVal = T is string ? "" : 0

function getValue<T>(val?: T): T
{
const defVal = "FIXME" as unknown as T // <---- get default value based on T
return val ?? defVal;
}
const s = getValue<string>();   // want s === ""
const n = getValue<number>(2);  // want n === 2

根据我自己的经验和@MikeS.的评论。,我认为,尽管Typescript在很多方面都很好,但这是一个简单的情况,即它不能向代码添加任何有用的值,因为它不会在运行时保留类型信息

因此,使用";老派;方法。

function getValueString(val?: string): string
{
return val ?? "";
}
function getValueNumber(val?: number): number
{
return val ?? 0
}
const s = getValueString();
const n = getValueNumber(2);
console.log(s, n);

TypeScript仅在编译时存在,因此类型不能用于影响函数将返回的运行时值。

您可以修改函数以使用重载签名,这样您就可以根据值的类型进行推断,或者请求默认类型的值(取自您创建的对象(。下面是一个如何做到这一点的例子:

TS游乐场

const defaults = {
array: [] as unknown[],
bigint: 0n,
boolean: false,
null: null,
number: 0,
object: {} as Record<PropertyKey, unknown>,
string: '',
undefined: undefined,
};
function getValue <T>(typeWanted: 'infer'): undefined;
function getValue <T>(typeWanted: 'infer', value: T): T;
function getValue <T extends keyof typeof defaults>(typeWanted: T): typeof defaults[T];
function getValue <T>(typeWanted: keyof typeof defaults | 'infer', value?: T) {
if (typeWanted === 'infer') return value;
return defaults[typeWanted];
}
console.log(getValue('array')); // unknown[]: []
console.log(getValue('bigint')); // bigint: 0n
console.log(getValue('boolean')); // boolean: false
console.log(getValue('null')); // null: null
console.log(getValue('number')); // number: 0
console.log(getValue('object')); // Record<PropertyKey, unknown>: {}
console.log(getValue('string')); // string: ""
console.log(getValue('undefined')); // undefined: undefined
console.log(getValue('infer')); // undefined
console.log(getValue('infer', 2)); // 2
console.log(getValue('infer', 'hello')); // "hello"
console.log(getValue('infer', ['hello', 'world'])); // string[]: ["hello", "world"]
console.log(getValue('infer', ['hello', 'world'] as const)); // readonly ["hello", "world"]: ["hello", "world"]
// ...etc.

最新更新