TypeScript 推断 T inner<T> for Outer<T> 的通用类型
TypeScript infer generic type of T in Inner<T> for Outer<T>
我有一个 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
class 包装了 Inner<T>
的一个实例。我也想不时访问Inner。因此我保留了 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?
Typescript 不会从其他类型参数推断 T
。基本上,由于 T
没有出现在构造函数的参数列表中,因此不会对其进行任何推断。您可以通过多种方式解决此问题。
最简单的方法之一是在构造函数中使用交集为打字稿提供 T
的推理站点:
class Outer<TInner extends Inner<T>, T> {
constructor(public inner: TInner & Inner<T>) { }
getV(): T {
return this.inner.v;
}
}
您还可以使用某种形式的相对类型从 TInner
中提取 T
,例如索引访问类型:
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;
}
}
我有一个 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
class 包装了 Inner<T>
的一个实例。我也想不时访问Inner。因此我保留了 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?
Typescript 不会从其他类型参数推断 T
。基本上,由于 T
没有出现在构造函数的参数列表中,因此不会对其进行任何推断。您可以通过多种方式解决此问题。
最简单的方法之一是在构造函数中使用交集为打字稿提供 T
的推理站点:
class Outer<TInner extends Inner<T>, T> {
constructor(public inner: TInner & Inner<T>) { }
getV(): T {
return this.inner.v;
}
}
您还可以使用某种形式的相对类型从 TInner
中提取 T
,例如索引访问类型:
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;
}
}