【发布时间】:2021-01-08 01:33:08
【问题描述】:
考虑以下 Typescript 代码:
class OrderFixture {
orderId: string;
constructor() {
this.orderId = "foo";
}
}
class DecisionFixture {
decisionId: string;
constructor() {
this.decisionId = "bar";
}
}
class FixtureStore {
order = () => new OrderFixture();
decision = () => new DecisionFixture();
}
const fixtureStore = new FixtureStore();
export function getFixture<
K extends keyof FixtureStore,
T extends ReturnType<FixtureStore[K]>
>(entityName: K): T {
return fixtureStore[entityName](); // ERROR: Type 'OrderFixture' is not assignable to type 'T'.
}
它会产生以下类型错误:
Type 'OrderFixture | DecisionFixture' is not assignable to type 'T'.
'OrderFixture | DecisionFixture' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'OrderFixture | DecisionFixture'.
Type 'OrderFixture' is not assignable to type 'T'.
'OrderFixture' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'OrderFixture | DecisionFixture'.ts(2322)
这是playground。
这种类型的错误引发的问题似乎有一个fairly canonical answer,但我看不出那里列出的两个原因与我的代码之间有任何相关的相似之处。
如果我按照this answer 中的建议强制将返回值转换为T,我在调用getFixture 时会得到正确的类型。为什么 Typescript 不为我推断这些类型?
【问题讨论】:
-
-
这是一个很好的问题,顺便说一下,我以前也遇到过类似的问题。我会这么说是因为推断可以达到
OrderFixture | DecisionFixture,但你只会指定其中一个,所以你必须说出它使用类型转换的两个中的哪一个...... -
如果你转换为
any更奇怪的是,被调用者仍然得到正确的推断类型。嗯
标签: typescript