TypeScript中如何不使用泛型获取同级属性的精确类型
问题场景
参考如下代码片段:
const useExample = (options: { Component: React.ComponentType props: React.ComponentProps<typeof options.Component> }) => { return } const Foo = (props: {bar: string; baz: number}) => <></> const Qux = () => { const a = useExample({Component: Foo, props: {bar: 2, baz: 'y'}}) }
代码的设计意图是根据传入的Component自动推导允许传入的props类型,但实际类型校验完全失效:在Qux中调用useExample时,IntelliSense只会将props识别为空对象类型,bar、baz字段传入错误类型也不会触发类型报错。
核心疑问:是否存在不使用泛型即可实现该类型推导效果的可行方案?
答案
不存在不使用泛型即可实现该效果的可行方案。
原写法失效的核心原因是:TypeScript 不会对同一个参数对象内的字段做跨字段的、基于实际传入值的反向推导。你在类型标注里提前将Component字段的类型写死为宽泛的React.ComponentType,TS计算props字段类型时,只会直接读取这个静态标注类型对应的ComponentProps结果——也就是默认的空对象{},完全不会感知到你实际传入的是Foo组件,自然无法做对应props的类型校验和提示。
要实现「传入什么组件就自动校验对应props」的效果,必须通过泛型捕获传入组件的具体窄类型,再基于这个窄类型计算props的类型,正确实现代码如下:
const useExample = <T extends React.ComponentType<any>>(options: { Component: T props: React.ComponentProps<T> }) => { return } const Foo = (props: {bar: string; baz: number}) => <></> const Qux = () => { // 此处会直接抛出类型错误:bar类型不匹配、baz类型不匹配,IntelliSense也会正确提示props的所有字段 const a = useExample({Component: Foo, props: {bar: 2, baz: 'y'}}) }
目前TypeScript没有提供其他语法可以在不使用泛型的前提下,实现同一个对象参数内两个字段的类型依赖推导。
内容的提问来源于stack exchange,提问作者Michał Piotr Dzienisiewicz
相关产品推荐
相关产品推荐

