为什么这种类型保护不适用于泛型参数



考虑以下代码(TS游乐场(:

function identity<T>(value: T): T {
if (typeof value === 'string') {
return value.replace('foo', 'bar'); // <-- ERROR
}
return value;
}

它导致错误Type 'string' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.

类型保护似乎不足以缩小泛型参数的类型并执行字符串操作。

为什么会出现此错误,我该如何解决?

假设函数被调用为这样的

const example: 'foo' = 'foo';
const result = identity(example);

根据函数的类型定义,由于T"foo"(即特定字符串,而不是一般的string(,因此也必须向i返回"foo"。但是函数内部的代码将返回"0";条";相反,它违反了类型。


要执行您想要的操作,您需要使用函数重载为字符串大小写赋予不同于其他大小写的类型。例如:

function identity<T>(value: string): string;
function identity<T>(value: T): T;
function identity<T>(value: T): T | string {
if (typeof value === 'string') {
return value.replace('foo', 'bar');
}
return value;
}

如果用T=="foo"调用此代码,那么typescript将看到"foo"的值与value: string兼容,因此函数的第一个类型定义匹配。根据该类型定义,返回值因此是一般的string

游乐场链接

最新更新