Typescript :: 相关的通用约束
Typescript :: Related Generic Constraints
在 React
中,我有一个像这样的通用接口:
interface BaseProps<T> {
data: T;
}
我的代码的使用者将扩展它以定义他们自己的 Props
和 Component
:
interface MyProps extends BaseProps<string> {
...
}
const MyComponent: React.FC<MyProps> = ({ data }) => {
...
}
我想写一个接受这样一个组件的方法,returns 是一个与 MyComponent.data
相同类型的值。这就是我正在努力解决的问题。我正在尝试编写此方法并将其调用为:
function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): T {
return ...
}
const ret1 = myFunc(MyComponent);
const ret2 = myFunc<string, MyProps>(MyComponent);
ret2
具有正确的类型 string
但 ret
具有 unknown
类型。有没有一种方法可以在 myFunc
方法中强制执行约束,以便正确键入 ret1
而无需我在 <>
中显式声明类型?
更新
@futut 和@proton 都给出了(几乎)相同的解决方案,在这种情况下显然有效!荣誉!
然而,我在这里写的示例代码有点过于简单了。如果我将 BaseProps
界面更改为:
interface BaseProps<T> {
callback: (value: T) => void;
}
那我就不能再用U["data"]
了。在这种情况下,有没有办法能够 return MyComponent.callback
中 value
参数类型的值?
PS:很抱歉在这里转移球门柱。我不擅长过于简单化。
TypeScript 不知道提供的类型 U
也可以告诉它 T
是什么。您可以改为使用单个类型参数并使用索引访问来获取其 data
属性:
的类型
function myFunc<T extends BaseProps<any>>(component: React.FC<T>): T["data"] {
/* ... */
}
只需明确告知 typescript,BaseProps.data
的类型将成为函数 return 值,如下所示:
function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): U['data'] {
...
}
这样您就不必将类型传递给泛型语句 (<>
),只要传递给 myFunc
的组件类型正确即可。
编辑:
关于问题的第二个版本:
这里的事情变得棘手。您可以使用 infer
关键字指向回调的值,如下所示:
function myFunc<T extends BaseProps<any>>(
component: React.FC<T>,
): T['callback'] extends (a: infer R) => void ? R : never {
...
检查有关该关键字的文档:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
在 React
中,我有一个像这样的通用接口:
interface BaseProps<T> {
data: T;
}
我的代码的使用者将扩展它以定义他们自己的 Props
和 Component
:
interface MyProps extends BaseProps<string> {
...
}
const MyComponent: React.FC<MyProps> = ({ data }) => {
...
}
我想写一个接受这样一个组件的方法,returns 是一个与 MyComponent.data
相同类型的值。这就是我正在努力解决的问题。我正在尝试编写此方法并将其调用为:
function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): T {
return ...
}
const ret1 = myFunc(MyComponent);
const ret2 = myFunc<string, MyProps>(MyComponent);
ret2
具有正确的类型 string
但 ret
具有 unknown
类型。有没有一种方法可以在 myFunc
方法中强制执行约束,以便正确键入 ret1
而无需我在 <>
中显式声明类型?
更新
@futut 和@proton 都给出了(几乎)相同的解决方案,在这种情况下显然有效!荣誉!
然而,我在这里写的示例代码有点过于简单了。如果我将 BaseProps
界面更改为:
interface BaseProps<T> {
callback: (value: T) => void;
}
那我就不能再用U["data"]
了。在这种情况下,有没有办法能够 return MyComponent.callback
中 value
参数类型的值?
PS:很抱歉在这里转移球门柱。我不擅长过于简单化。
TypeScript 不知道提供的类型 U
也可以告诉它 T
是什么。您可以改为使用单个类型参数并使用索引访问来获取其 data
属性:
function myFunc<T extends BaseProps<any>>(component: React.FC<T>): T["data"] {
/* ... */
}
只需明确告知 typescript,BaseProps.data
的类型将成为函数 return 值,如下所示:
function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): U['data'] {
...
}
这样您就不必将类型传递给泛型语句 (<>
),只要传递给 myFunc
的组件类型正确即可。
编辑:
关于问题的第二个版本:
这里的事情变得棘手。您可以使用 infer
关键字指向回调的值,如下所示:
function myFunc<T extends BaseProps<any>>(
component: React.FC<T>,
): T['callback'] extends (a: infer R) => void ? R : never {
...
检查有关该关键字的文档: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html