打字稿通用选择错误的类型

问题描述 投票:0回答:1

假设我有四门课:

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
实例应该不是问题。

非常感谢您对改进我的打字提出任何建议。

typescript generics polymorphism subclass
1个回答
0
投票

如果这是您的用例的确切要求,这里是您如何限制泛型 -

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());
© www.soinside.com 2019 - 2024. All rights reserved.