Typescript 类型';这是"K"和"x27,;不可分配给类型';不可为空<;这[K]>';
我不明白为什么typescript会为此抛出错误:Typescript 类型';这是"K"和"x27,;不可分配给类型';不可为空<;这[K]>';,typescript,typescript-generics,Typescript,Typescript Generics,我不明白为什么typescript会为此抛出错误: public saveGet<K extends keyof this> (key: K, def: NonNullable<this[K]>): NonNullable<this[K]> { if (this[key] !== null && this[key] !== undefined) { return this[key] } else { re
public saveGet<K extends keyof this> (key: K, def: NonNullable<this[K]>): NonNullable<this[K]> {
if (this[key] !== null && this[key] !== undefined) {
return this[key]
} else {
return def
}
}
publicsaveget(键:K,定义:不可为空):不可为空{
if(此[键]!==null&此[键]!==未定义){
返回此[键]
}否则{
返回def
}
}
错误:
Type 'this[K]' is not assignable to type 'NonNullable<this[K]>'.
Type 'this[keyof this]' is not assignable to type 'NonNullable<this[K]>'.
Type 'this[string] | this[number] | this[symbol]' is not assignable to type 'NonNullable<this[K]>'.
Type 'this[string]' is not assignable to type 'NonNullable<this[K]>'.ts(2322)
类型“this[K]”不可分配给类型“nonnull”。
类型“this[keyof this]”不可分配给类型“NonNullable”。
类型“this[string]| this[number]| this[symbol]”不可分配给类型“nonnull”。
类型“this[string]”不可分配给类型“NonNullable”。ts(2322)
据我所知,typescript编译器应该能够从这个[key]
中排除null
和undefined
(因此进行比较),因此我应该能够返回它
有人能解释一下吗?
如果已经提出了这个问题,我很抱歉。这里的主要问题是,TypeScript编译器没有执行必要的高阶推理,以查看值何时可分配给依赖于尚未指定的类型参数的。在示例代码中,您希望编译器使用它来实现
this[key]
应该从this[K]
缩小到nonnull
。不幸的是,K
和在saveGet()
的主体中都没有指定。(K
显然是一个泛型参数,但this
是一种“虚拟”泛型参数。您不必声明它,但它的行为类似于在类体内未指定的参数,并且在拥有类实例时指定。)因此编译器不知道如何缩小this的类型[key]
。关于这一点的典型公开问题是,它讨论了试图解决这一问题所涉及的挑战
这里的解决方法可能是编写一个脚本来控制收窄行为
一个不太重要但仍然相关的问题是,当您使用括号索引访问时,编译器不会控制基于流的对象属性收缩;有关详细信息,请参阅。因此,很遗憾,检查
此[key]
不会对此[key]
的后续检查产生任何影响。这里的解决方法是分配此属性[键]
到它自己的变量并检查
这意味着您的问题的当前解决方案如下所示:
// user defined type guard function
function isNonNullable<T>(x: T): x is NonNullable<T> {
return x !== null && x !== undefined
}
public saveGet<K extends keyof this>(
key: K, def: NonNullable<this[K]>): NonNullable<this[K]> {
const thisKey = this[key]; // save into own variable
if (isNonNullable(thisKey)) {
return thisKey; // okay now
} else {
return def
}
}
//用户定义的类型保护函数
函数不可为空(x:T):x不可为空{
返回x!==null&&x!==未定义
}
公共储蓄(
键:K,定义:不可为空):不可为空{
const thisKey=this[key];//保存到自己的变量中
如果(isNonNullable(thisKey)){
返回此键;//现在可以了
}否则{
返回def
}
}
这里的主要问题是,TypeScript编译器没有执行必要的高阶推理,以查看值何时可分配给依赖于尚未指定的类型参数的。在示例代码中,您希望编译器使用来实现
此[key]
应该从此[K]缩小
到不可为空
。不幸的是,K
和在saveGet()
的主体中都没有指定(K
显然是一个泛型参数,但是这个
有点“虚拟”泛型参数。您不必声明它,但它的作用类似于在类体内未指定的参数,并且在您有类的实例时指定。)因此编译器不知道如何缩小此[key]的类型
。关于这一点的典型公开问题是,它讨论了试图解决这一问题所涉及的挑战
这里的解决方法可能是编写一个脚本来控制收窄行为
一个不太重要但仍然相关的问题是,当您使用括号索引访问时,编译器不会控制基于流的对象属性收缩;有关详细信息,请参阅。因此,很遗憾,检查
此[key]
不会对此[key]
的后续检查产生任何影响。这里的解决方法是分配此属性[键]
到它自己的变量并检查
这意味着您的问题的当前解决方案如下所示:
// user defined type guard function
function isNonNullable<T>(x: T): x is NonNullable<T> {
return x !== null && x !== undefined
}
public saveGet<K extends keyof this>(
key: K, def: NonNullable<this[K]>): NonNullable<this[K]> {
const thisKey = this[key]; // save into own variable
if (isNonNullable(thisKey)) {
return thisKey; // okay now
} else {
return def
}
}
//用户定义的类型保护函数
函数不可为空(x:T):x不可为空{
返回x!==null&&x!==未定义
}
公共储蓄(
键:K,定义:不可为空):不可为空{
const thisKey=this[key];//保存到自己的变量中
如果(isNonNullable(thisKey)){
返回此键;//现在可以了
}否则{
返回def
}
}
谢谢你的精彩解释!谢谢你的精彩解释!