假设我有四门课:
A
,带有通用 T
和 B
,将通用 T
指定为 X
。
最后一个类是 Y
,它使用新属性 X
扩展了 baz
。
class A<T> {
foo: T;
}
class B extends A<X> {}
class X {}
class Y extends X {
baz: string;
}
// works!
new B().foo = new Y()
现在我想创建一个类型安全的函数,为
foo
: 赋值
function test<T, V extends A<T>>(t: T, v: V) {
v.foo = t;
}
此函数获取
foo
(t
) 的值和 A
或其子类 (v
) 的实例,并将该值分配给它的 foo
属性。
但是,如果我想将 Y
的实例分配给 B
的实例,则会收到错误:
// Typescript error: Property 'baz' is missing in type 'X' but required in type 'Y'.
test(new Y(), new B());
这就是我被困住的地方。 如何使打字稿为
test
函数的泛型选择正确的类型。
应该发生的是,打字稿理解 B
要求 foo
是 X
的实例,因此为其分配 Y
实例应该不是问题。
非常感谢您对改进我的打字提出任何建议。
如果这是您的用例的确切要求,这里是您如何限制泛型 -
class A<T> {
foo!: T;
}
class B extends A<X> { }
class X { }
class Y extends X {
baz!: string;
}
// works!
new B().foo = new Y()
function test<U extends X, T extends U, V extends A<U>>(t: T, v: V) {
v.foo = t;
}
test(new Y(), new B());
或者,你可以做类似this的事情,告诉打字稿Y处于逆变位置-
class A<T> {
foo!: T;
}
class B extends A<X> { }
class X { }
class Y extends X {
baz!: string;
}
type Test<in T, V> = (a: T, b: V) => void;
const test: Test<Y, B> = (t, v) => {
v.foo = t;
}
test(new Y(), new B());