我试着在redux绑定中做一些connect()
。下面是我在组件中注入道具的特例:
export function withAdditionalProps<T, I>(
injectedProps: I,
WrappedComponent: React.ComponentType<T>,
): React.ComponentType<Omit<T, keyof I>> { ... }
如果我声明注入的道具类型(I
泛型),它可以正常工作,但如果我想在不声明这些类型的情况下执行临时操作(省略动态注入的道具键),该怎么办?如何从传递的道具中确定钥匙?举个例子,我试过这样的方法:
export function withAdditionalProps<T>(
injectedProps: { [key: string]: unknown },
WrappedComponent: React.ComponentType<T>,
): React.ComponentType<Omit<T, keyof typeof injectedProps>> { ... }
const InjectedComponent = withAdditionalProps<AppState>(
{
counter: 0
},
(props) => (<div>{props.counter}</div>)
);
但是它不正确:编译器在呈现组件时会抛出一个错误。查看屏幕截图(testProp是组件的“原生”支柱)
也许任何人都能帮我。
发布于 2020-06-03 05:13:09
简而言之,你的第二个例子在打字稿中是不可能的。
问题是,{ [key:string]: unknown }
类型总是将所有可能的字符串作为键捕获,而不是缩小到在特定调用中使用的具体字符串,这将使在这里使用Omit
成为可能。
实际上,与Omit
一起使用的{ [key:string]: unknown }
只是省略了所有可能的键,因此忽略了T
中的所有本机道具。这在将来可能通过否定类型特性实现,但目前唯一的方法是通过声明的类型变量,如第一个示例所示。
但是,函数定义中声明的类型变量并不要求您也为每个调用声明它们。参见下面的代码-编译器将从调用函数时传递的具体参数推断T
和I
。因此,在实践中,这里唯一的区别在于您的特定类型定义,而且老实说,无论哪种方式,它似乎都是类似的工作/可读性。
function foo<T, I>(t: T, i: I): Omit<T, keyof I> {
return { ...t, ...i }
}
// notice explicitly declaring foo<{ a: number, b: number}, { c: number }>
// is NOT necessary. The correct types are just inferred from the args you pass.
const bar = foo({ a: 1, b: 2 }, { b: 3 })
bar.a // OK
bar.b // ERROR, since b is omitted
发布于 2020-06-05 07:24:06
如果在泛型参数中同时捕获组件的Props
类型和注入的支持类型,则可以完成以下工作:
export function withAdditionalProps<C extends unknown, I extends object>(
injectedProps: I,
WrappedComponent: React.ComponentType<C>,
): React.ComponentType<Omit<C, keyof I>> {
// ...
}
与其将AppState
作为泛型参数传递,不如确保TypeScript有足够的上下文来推断它。您可以通过在包装组件中声明AppState
来做到这一点:
interface AppState {
counter: number;
}
const InjectedComponent = withAdditionalProps(
{
counter: 0,
},
(props: AppState) => <div>{props.counter}</div>,
);
const el = <InjectedComponent />; // OK
const InjectedComponent2 = withAdditionalProps(
{
counter2: 0,
},
(props: AppState) => <div>{props.counter}</div>,
);
const el2 = <InjectedComponent2 />; // error: Property 'counter' is missing
TypeScript 不会让您指定某些泛型参数,但会让其他参数推断.如果您想通过泛型传递AppState
,标准的解决方法是使用两个函数,一个函数具有显式泛型参数,另一个函数具有推断参数。在您的示例中,如下所示:
export function withAdditionalProps<PropsType>(): <I extends unknown>(
injectedProps: I,
WrappedComponent: React.ComponentType<PropsType>,
) => React.ComponentType<Omit<PropsType, keyof I>> {
// ...
}
下面是你如何使用它:
interface AppState {
counter: number;
}
const InjectedComponent = withAdditionalProps<AppState>()({
counter: 0,
},
props => <div>{props.counter}</div>,
);
const el = <InjectedComponent />; // OK
const InjectedComponent2 = withAdditionalProps<AppState>()(
{
counter2: 0,
},
props => <div>{props.counter}</div>,
);
const el2 = <InjectedComponent2 />; // error: Property 'counter' is missing
我不太清楚在你的截图中错误信息背后是怎么回事。如果你能分享文本或链接,我可以看一看。
https://stackoverflow.com/questions/61782009
复制相似问题