>假设我有一个像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>
任何等价的东西都会很棒。
您可以使用推断:
type TypeWithGeneric<T> = T[]
type extractGeneric<Type> = Type extends TypeWithGeneric<infer X> ? X : never
type extracted = extractGeneric<TypeWithGeneric<number>>
// extracted === number
操场
您可以使用模式匹配:
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);
以为我会分享一个真实世界的例子来提取MatDialogRef<T, R = any>
R
泛型类型,即 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 使用的机制相同,但演示了如何为特定用途制作"目标"提取器。