给定以下类型
interface Base {
id: string;
}
interface A extends Base {
propA: string;
}
interface B extends Base {
propB: string;
}
我想表达一个MyGeneric<T>
具有以下约束的泛型:
T
必须是一个对象T
密钥必须是 string
T
值必须为instanceOf Base
(类型为Base
,或为扩展Base的类型)
(3. wasT
值必须与Base
接口兼容,但已对其进行了改写,以免造成不理解)
我试过了
interface MyConstraint {
[key: string]: Base
}
interface MyGeneric<T extends MyConstraint> {
data: T
}
但是在这种情况下,当用户想要使用它时,它有两个缺点:
interface userDefinedInterface1 {
a: A;
b: B;
}
function foo1(p: MyGeneric<userDefinedInterface1>):void {
//drawback 1: this throws TS2344:
//Type 'userDefinedInterface1' does not satisfy the constraint 'userDefinedInterface1'. //Index signature is missing in type 'userDefinedInterface1'.
}
//to solve drawback 1, the user has to extend MyConstraint
interface userDefinedInterface2 extends MyConstraint {
a: A;
b: B;
}
function foo2(p: MyGeneric<userDefinedInterface2>):void {
//drawback 2: here, ts considers every string property as valid because of [key: string]
console.log(p.data.arbitraryKey);//this is valid
}
有没有一种方法可以定义interface MyGeneric<T>
尊重上述3个约束条件而又没有这2个缺点?
我认为这应该可以解决您的两个缺点:
type MyConstraint<T> = {
[K in keyof T]: T[K] extends Base ? T[K] : never;
};
interface MyGeneric<T extends MyConstraint<T>> {
data: T;
}
为使MyConstraint
通用的小价格。现在,如果您执行了以下操作,那么您的两个示例都应该可以正常工作:
interface UserDefinedInterface3 {
a: A;
b: B;
c: string;
}
type Wrong = MyGeneric<UserDefinedInterface3>;
您会收到一条错误消息,指出属性类型c
不兼容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句