javascript - 对期望为 'number | string | undefined' 的属性使用泛型类型值

标签 javascript reactjs typescript

这个问题使用 React 代码,但特定于 typescript 而不是 react。

我正在使用一个简化的示例来尝试使其更易于阅读。我有一个组件 MyList,它接受一个传递给 props 类型的泛型类型参数。

此泛型类型推断出一个用于生成子组件的对象。我想使用 T[keyof T] 的值来为每个子组件设置键 ||它在 T[] 中的索引。

创建列表并使用索引没问题,但我无法弄清楚如何正确键入 listKey 以便它可以与 reacts key 属性一起使用期待 号码 |字符串 |未定义

type MyListProps<T> = {
  list: T[],
  listKey: keyof T,
  contentKey: keyof T
}

class MyList<T extends object> extends React.Component<MyListProps<T>, any> {
  public render() {
    return (
      <div>
        { this.props.list.map((value: T, index: number) => {
            const key = value[this.props.listKey];
            return (
              // Type T[keyof T] is not assignable 
              // to type 'number | string | undefined'
              <Item key={key}>{value[this.props.contentKey]}</Item>
            );
        }
      </div>
    );
  }
}

我如何推断 listKey 类型可分配给使用泛型的预期类型的​​ react key Prop ?

最佳答案

由于您希望将索引访问的结果分配给 key,因此您需要限制该索引操作可以返回的内容。一种方法是在 T 上使用约束:

class MyList2<T extends Record<string, string | number >> extends React.Component<MyListProps2<T>, any> {
  public render() {
    return (
      <div>
        { this.props.list.map((value: T, index: number) => {
            const key = value[this.props.listKey];
            return (
              <Item key={key}>{value[this.props.contentKey]}</Item>
            );
        })}
      </div>
    );
  }
}

这确实有限制您可以在 T 中拥有的可能值的缺点,这可能是一个问题(或不取决于您的用例)。

另一个更复杂的选项是限制使用 listKey 的索引将返回什么。这确实需要一个额外的类型参数,但它允许更大的灵 active :

type MyListProps<T, LK extends PropertyKey> = {
  list: Array<T & Record<LK, string>>,
  listKey: LK,
  contentKey: keyof T
}
declare const Item: React.FC<{}>

class MyList<T, LK extends PropertyKey> extends React.Component<MyListProps<T, LK>, any> {
  public render() {
    return (
      <div>
        {this.props.list.map((value, index: number) => {
          const key = value[this.props.listKey];
          return (
            <Item key={key}>{value[this.props.contentKey]}</Item>
          );
        })}
      </div>
    );
  }
}

let x = <MyList listKey="a" contentKey="a" list={[
  { a: "", b: 0, p: {} }
]} ></MyList>

或者在这种情况下您可以放弃类型安全而只使用类型断言。

关于javascript - 对期望为 'number | string | undefined' 的属性使用泛型类型值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56182311/

相关文章:

javascript - 按钮工具提示上的数据标题未更新

jquery - 单击事件在 Angular 5 中无法正常工作

javascript - 子类的 typescript 定义作为参数

javascript - NextJS - 在一页上进行多次获取的动态路由

javascript - 从 DOM 中删除除一个子树之外的所有节点

javascript - 如何将此代码从 UI Route 更改为核心 ng-Route

javascript - ReactJS - 使用 Mutation Observer 检测第三方 DOM 插入

javascript - 如何在 gulp 中正确包含 requirejs 和 React & JSX

javascript - Promise 仅在页面刷新时正确解析

javascript - 在 Objection.js 中以多对多方式插入额外字段