TypeScript:如何从类型中提取泛型参数?

时间:2017-06-30 16:38:55

标签: typescript

假设我的类型为React.ComponentClass<Props>,我想引用Props部分,但在我目前的背景下未命名。

举例说明:

const x = makeComponent(); // typeof x = React.ComponentClass<Something>

在这种情况下,我可以使用typeof x,但这不会直接给我 访问Something类型。

我想要的是这样的:

type GetPropsType<C extends React.ComponentClass<P>> = P

这样我就可以使用Something

类型提取GetPropsType<typeof x>

任何等同的东西都会很棒。

4 个答案:

答案 0 :(得分:9)

您可以使用推理:

type TypeWithGeneric<T> = T[]
type extractGeneric<Type> = Type extends TypeWithGeneric<infer X> ? X : never

type extracted = extractGeneric<TypeWithGeneric<number>>
// extracted === number

enter image description here

答案 1 :(得分:2)

您可以使用模式匹配:

namespace React {
    export class ComponentClass<T> {}
}

function doSomethingWithProps<T>(x : React.ComponentClass<T>) : T {
    return null as T;
}

class Something {}
let comp = new React.ComponentClass<Something>();
const instanceOfSomething = doSomethingWithProps(comp);

答案 2 :(得分:0)

我想分享一个真实的例子来提取R的通用类型MatDialogRef<T, R = any>,这是Angular材质的对话框。

我经常有这样的组件,其中输出“模型”是一个简单的接口,不完全值得使用自己的命名类型。

export class DialogPleaseWaitComponent implements OnInit {

  constructor(@Inject(MAT_DIALOG_DATA) public data: DialogPleaseWaitModel,
              public dialogRef: MatDialogRef<DialogPleaseWaitModel, { timedOut: boolean }>) { 

  }

所以我想到了:

extractMatDialogResponse<T>

我使它可以在两种“模式”下工作,要么采用组件类型,要么采用MatDialogRef本身。所以我可以放extractMatDialogResponse<DialogPleaseWaitComponent>并退回{ timedOut: boolean }:-)

是-如果T是组件类型,则它要求dialogRef是属性的确切名称,并且确实需要公开。

type extractMatDialogResponse<T = MatDialogRef<any, any> | { dialogRef: MatDialogRef<any, any> }> = 
     T extends MatDialogRef<any, infer R> ? R :                                                                                                          
     T extends { dialogRef: MatDialogRef<any, infer R> } ? R : never;

是的,这与Xiv使用的机制相同,但是演示了如何针对特定用途制作“目标”提取器。

答案 3 :(得分:-5)

TypeScript泛型是用于类型检查的编译时功能,在转换后不可用作JavaScript运行时功能。您可能需要查看this answer,其中有一个非常好的示例,说明如何构造类,以便您可以从类方法访问泛型的表示。