我有一個Inner<T>包裝通用型別值的介面:
interface Inner<T> {
v: T;
}
該介面有不同的實作:
class SomeInner<T> implements Inner<T> {
constructor(public v: T) {}
some = true;
}
class SomeOtherInner<T> implements Inner<T> {
constructor(public v: T) {}
someOther = true;
}
有一個Outer類包裝了 的實體Inner<T>。我也想不時訪問Inner。因此,我保留內部的實際型別:
class Outer<T, TInner extends Inner<T>> {
constructor(public inner: TInner) { }
getV(): T {
return this.inner.v;
}
}
不幸的是,TS 無法推斷 Outer 中 T 的型別——盡管它知道 TInner 的型別及其泛型型別:
const someInnerInst = new SomeInner("foo" as string);
const outerInstOfSomeInner = new Outer(someInnerInst);
const vFromOuter = outerInstOfSomeInner.getV(); // Type: unknown // <- SHOULD BE string
const vFromInner = outerInstOfSomeInner.inner.v; // Type: string
有沒有辦法幫助 TypeScript 在 Outer 中推斷 T?
您可以在 Playground 中嘗試完整示例。
uj5u.com熱心網友回復:
Typescript 不會T從其他型別引數推斷。基本上,由于T沒有出現在建構式的引數串列中,因此不會對其進行推斷。您可以通過多種方式解決此問題。
最簡單的方法之一是使用交集T在建構式中為打字稿提供推理站點:
class Outer<TInner extends Inner<T>, T> {
constructor(public inner: TInner & Inner<T>) { }
getV(): T {
return this.inner.v;
}
}
游樂場鏈接
你也可以使用某種形式的相對打字的提取T從TInner,例如索引訪問型別:
class Outer<TInner extends Inner<any>> {
constructor(public inner: TInner) { }
getV(): TInner['v'] {
return this.inner.v;
}
}
游樂場鏈接
或使用條件型別:
type InnerTypeParam<T extends Inner<any>> = T extends Inner<infer U> ? U : never
class Outer<TInner extends Inner<any>> {
constructor(public inner: TInner) { }
getV(): InnerTypeParam<TInner> {
return this.inner.v;
}
}
游樂場鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/404781.html
標籤:
