在具有泛型类型上的Map类型的函数中,遇到了一个类型歧视的bug。我尽量使复现变得简单。
TypeScript 版本: 4.1.0-beta
搜索词:
区分,泛型,Map类型,严格空值检查关闭
代码
type Mapping<T> = { [key in keyof T]?: string | (() => string) };
function foo<T>(mapping: Mapping<T>) {
const results: {[key: string]: string} = {};
for (const key in mapping) {
const valueTransform = mapping[key];
if (typeof valueTransform === 'function') {
results[key] = valueTransform(); //! This expression is not callable...
} else if(typeof valueTransform === 'string') {
results[key] = valueTransform;
}
}
return results;
}
预期行为:
实际行为:
strictNullChecks:false
我得到了以下错误:
This expression is not callable.
Not all constituents of type 'string | (() => string)' are callable.
Type 'string' has no call signatures.
如果你把它改回 true
,它将按预期工作。似乎与泛型和Map类型的组合有关,如果直接改为引用 Foo
,代码将正常编译。type Mapping<T> = { [key in keyof Foo]?: string | (() => string) };
此外,区分似乎只在 typeof valueTransform === 'function'
上失效。
**Playground 链接:**Playground 链接
相关问题:
3条答案
按热度按时间ykejflvf1#
问题可以通过以下示例再现:
错误如下:
将类型保护从
typeof value === 'function'
更改为value instanceof Function
后,问题得到解决。bksxznpy2#
在通用情况下,我认为
insatnceof
的行为是错误的,这应该是一个错误。如果T
是(a: string) => string
,那么类型保护不会将T
从 true 分支中排除:Playground Link
nfs0ujit3#
另一个示例:
播放