大佬教程收集整理的这篇文章主要介绍了使用过滤的 keyof 类型索引多态“this”类型,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
有关为什么以下代码似乎无法使用 ts 4.2.3 版进行编译的任何想法:
type numbersKeys<T extends BaseClass> = keyof {
// Keys where key is a String and value of key is a number
[K in keyof T as T[K] extends number ? (K extends String ? K : never) : never]: T[K]
};
class BaseClass {
printnumberKey(prop: numbersKeys<this>){
console.log(prop)
}
// Why doesnt this work?
printnumberValuePlusOne(prop: numbersKeys<this>) {
console.log(this[prop] + 1)
}
// Or this?
getnumber<T extends numbersKeys<this>,K extends this[T]>(prop: T) {
return this[prop];
}
// But this does?
getProperty<T extends keyof this>(prop: T): this[T] {
return this[prop];
}
}
class DerivedClass extends BaseClass {
StringProp: String = '';
numberProp: number = 0;
1: number;
}
let instance = new DerivedClass();
instance.printnumberKey('numberProp');
instance.printnumberValuePlusOne('numberProp');
console.log(instance.getnumber('numberProp'));
// Below should error
// instance.printnumberKey('StringProp');
// instance.printnumberValuePlusOne('StringProp');
// console.log(instance.getnumber('StringProp'));
// instance.printnumberKey(1);
// instance.printnumberValuePlusOne(1);
// console.log(instance.getnumber(1));
我希望能够使用 prop 参数来索引“this”,但编译器似乎无法理解 numberKeys 是“this”的键。是否有不同的方法来过滤 keyof 值,以便编译器了解我正在尝试做什么?
这是a link to the typescript playground example of this:
编辑:编辑示例以删除下面评论中提到的问题
您可以将 polymorphic this
type 视为隐式 generic 类型参数。在 BaseClass
的主体内部,未指定 this
类型;编译器只知道 this extends BaseClass
。只有当您创建实例时,this
才被隐式指定为实例的类型。
而且 TypeScript 编译器并不是特别擅长推理依赖于尚未指定的泛型类型参数的类型;尤其是当这些类型是 conditional types 时,例如 numbersKeys
中的 key remapping。一般而言,编译器只会延迟评估这些类型,并且无法验证是否可以为它们分配任何特定值。
这是 Typescript 的设计限制。我不确定是否有关于此的规范文档,但您可以查看诸如 microsoft/TypeScript#30728 或 microsoft/TypeScript#42896 之类的问题,这些问题已被标记为此类问题,因为编译器无法执行必要的分析来验证这一点。
所以你必须解决它。最简单的方法是使用 type assertion 告诉编译器 this[prop]
的类型是什么,因为它无法弄清楚:
printnumberValuePlusOneAssert(prop: numbersKeys<this>) {
console.log(this[prop] as unknown as number + 1)
}
这会将维护类型安全的负担从编译器转移到您身上,所以要小心;你可以写this[prop] as unknown as String
,它不会抱怨。
另一种解决方法是给 printnumberValuePlusOne()
一个 this
parameter 类型,其中编译器可以验证 this[prop]
是 number
:
printnumberValuePlusOne(
this: Record<numbersKeys<this>,number>,prop: numbersKeys<this>
) {
console.log(this[prop] + 1)
}
现在没有错误。如果 this
的类型为 Record<numbersKeys<this>,number>
,则编译器认为使用 numbersKeys<this>
类型的键对其进行索引是 number
。您甚至可以在这里获得某种类型安全性,尽管不是您所期望的。在对实例调用方法之前,不会真正检查 this
参数。如果实例的类型与 this
参数匹配,则调用将编译而不会出错:
instance.enforcedLater("numberProp"); // okay
否则,您将收到有关实例的警告。很难证明这种情况发生,因为您已经禁止坏键,因为 prop
是 numberKeys<this>
。如果您将其更改为以下内容:
enforcedLater<K extends keyof this>(
this: Record<K,prop: K
) {
console.log(this[prop] + 1);
}
您可以在实例本身上看到错误:
instance.enforcedLater("numberProp"); // okay
instance.enforcedLater("StringProp"); // error!
//~~~~~~ <-- Types of property 'StringProp' are incompatible.
Playground link to code
以上是大佬教程为你收集整理的使用过滤的 keyof 类型索引多态“this”类型全部内容,希望文章能够帮你解决使用过滤的 keyof 类型索引多态“this”类型所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。