请考虑下面的例子
export abstract class Definition {
[x: string]: string;
}
class A {
propA = 'A';
propB = 'B';
}
type AClassKey = keyof A;
const keyOfAClass: AClassKey = 'thisIsNotValidKey';
class B extends Definition {
propA = 'A';
propB = 'B';
}
type BClassKey = keyof B;
//This accepts any key because B extends Definition. How to make this accept only defined keys of B class (propA, propB)?
const keyOfBClass: BClassKey = 'thisIsValidKey';
// However if I map at least I get suggestion for defined keys (propA, propB)
type BClassMap = {[K in keyof B]: unknown}
const bMap:BClassMap = {propA: 'suggestedByAutoComplete', propB: 'suggestedByAutoComplete', someOther: 'notSuggestedButValid'};
是否可以使
type BClassKey
在扩展 class B
类时仅接受 abstract Definition
中定义的属性?
要将 keyof 限制为仅 B 的已定义属性,您可以引入一个显式声明这些属性的接口。然后,B将实现这个接口,确保在使用keyof时只考虑接口中的属性。
export abstract class Definition {
[x: string]: string;
}
interface IB {
propA: string;
propB: string;
}
class B extends Definition implements IB {
propA = 'A';
propB = 'B';
}
// Now keyof IB only refers to explicitly defined properties of B (propA, propB)
type BClassKey = keyof IB;
const keyOfBClass: BClassKey = 'propA'; // Valid
const invalidKeyOfBClass: BClassKey = 'thisIsNotValidKey'; // Error: Type '"thisIsNotValidKey"' is not assignable to type 'keyof IB'
此外,代码干净且可读,不需要复杂的 TypeScript 实用程序类型或排除。