从字符串 => 类型的映射推断反应道具类型时修复打字稿警告
Posted
技术标签:
【中文标题】从字符串 => 类型的映射推断反应道具类型时修复打字稿警告【英文标题】:Fixing typescript warnings when inferring react props types from map of string=>type 【发布时间】:2021-05-02 08:04:04 【问题描述】:我有一个名为Field
的 React 组件,它旨在呈现各种类型的表单输入,包括通过其他 React 组件实现的自定义输入。输入的类型由type
确定,它可以是已知字符串(keyof FIELD_TYPES
,这反过来又确定要创建的 React 组件)或任何类型的 React 组件(基于函数或类)。这已经实现了,但是我在尝试为实现提供正确的类型时遇到了一些问题。请注意,目标之一是确保正确推断道具,以便智能感知可以建议结果元素的有效属性。
This codesandbox 展示了我正在尝试修复的 3 个不同的 Typescript 警告。每个问题都带有// FIXME
注释;
(1) & (2): Type X 不能用于索引类型 'Y' - 到目前为止,我一直无法在这里找到满足 Typescript 的方法。
(3): Typescript 不接受自定义组件 - 不确定如何修改类型以允许这样做。
我也尝试过使用区分联合,但在尝试推断作为 type
传递或通过 FIELD_TYPES
映射解决的组件的 props 时遇到了困难。使用这种方法的答案也很有效。
const FIELD_TYPES =
text: "input",
checkbox: "input",
textarea: "textarea",
custom: Custom
as const;
type FieldTypeMap = typeof FIELD_TYPES
type KeysOfType<T, K> = [I in keyof T]: T[I] extends K ? I : never [keyof T]
type ReactComponentType<P = any> = React.ComponentType<P> | React.ExoticComponent<P>
type FieldTypeProps<Props = any> =
| type?: KeysOfType<FieldTypeMap, 'input'> & JSX.IntrinsicElements['input']
// FIXME(4): Is there any way to DRY this up?
| type: 'textarea' & JSX.IntrinsicElements['textarea']
| type: 'select' & JSX.IntrinsicElements['select']
// FIXME(5+6): How to include props for the provided react component type?
| type: ReactComponentType<Props> & Props // FIXME(5)
| type: KeysOfType<FieldTypeMap, ReactComponentType<Props>> & // FIXME(6)
提前致谢!
【问题讨论】:
我的第一反应:将custom
排除在FieldTypeMap
之外,并以不同方式处理。删除它实际上修复了一个错误“FIXME(1)”。关于“FIXME(2)”,问题在于自动类型保护在与&&
结合时不起作用。您必须分别检查每一件事。
我刚刚尝试通过重载为另一个问题写一些非常相似的东西,但我不能完全正确:tsplay.dev/rw2j1w
对于“FIXME(4)”:type PropsUnion = [K in keyof FieldTypeMap]: type: K & JSX.IntrinsicElements[FieldTypeMap[K]]
感谢琳达的帮助,非常感谢!我会看看我是否可以做任何额外的改进,如果可以的话,我会在这个帖子中跟进。
【参考方案1】:
所以问题是您需要从固有输入类型中分离自定义组件,以便您可以映射道具。此外,由于您正在重载现有的“类型”道具,因此需要省略它。
这是现在工作的代码:https://codesandbox.io/s/typescript-inferred-react-props-forked-hrh8p?file=/src/index.tsx
【讨论】:
以上是关于从字符串 => 类型的映射推断反应道具类型时修复打字稿警告的主要内容,如果未能解决你的问题,请参考以下文章
Typescript 和 React:使用 React.Component 和条件类型化道具时类型推断失败
使用 TypeScript 反应道具类型 - 如何拥有函数类型?