typescript - 输入和验证未知形状的对象数组

标签 typescript typescript-generics

我花了很多时间在这上面,我会很感激一些帮助。我想要一个组件(一个函数)接受一个对象数组,同时还验证对象的属性。
接口(interface)和数据:

interface ObjectWithId {
  id: string | number;
}

interface TableMeta<T extends ObjectWithId, K extends PropertyKey = keyof T> {
  data: T[];
  searchKey: K;
  onClick?: (item: T) => void;
}

interface Vegetable {
  id: number,
  label: string,
}

interface Fruit {
  id: number, 
  name: string,
}

const vegetableMeta: TableMeta<Vegetable> = {
  data: [],
  searchKey: 'label', // this only allows 'label' or 'id' 👍
}

const fruitMeta: TableMeta<Fruit> = {
  data: [],
  searchKey: 'name', // this only allows 'name' or 'id' 👍
  onClick: (item) => {item.id} // ✔️ has correct item type <---------------
}

const metas = [vegetableMeta, fruitMeta];
一个组件(一个简单的函数):
const metaParser = (metas: TableMeta<{id: number | string}, PropertyKey>[]) => {
  const id = metas[0].data[0].id; // should be `number | string`
}

metaParser(metas); // ❌ Type 'ObjectWithId' is not assignable to type 'Vegetable'
数组中对象的形状事先未知
关于如何使其工作的任何想法?
TS Playground

最佳答案

使其工作的一种方法是公开回调的类型并使其在处理对象集合时更通用。

interface ObjectWithId {
  id: string | number;
}

interface TableMeta<
  T extends ObjectWithId,
  K extends PropertyKey = keyof T,
  F extends (item: never) => void = (item: T) => void, // <--- expose the type
> {
  data: T[];
  searchKey: K;
  onClick?: F;
}

interface Vegetable {
  id: number,
  label: string,
}

interface Fruit {
  id: number, 
  name: string,
}

const vegetableMeta: TableMeta<Vegetable> = {
  data: [],
  searchKey: 'label',
}

const fruitMeta: TableMeta<Fruit> = {
  data: [],
  searchKey: 'name',
  onClick: (item) => {item.id}
}

const metas = [vegetableMeta, fruitMeta];

                                                make it more generic ---⌄
const metaParser = (metas: TableMeta<ObjectWithId, PropertyKey, (item: never) => void>[]) => {
  const id = metas[0].data[0].id;
}

metaParser(metas);

关于typescript - 输入和验证未知形状的对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65698415/

相关文章:

typescript - 如何缩小派生类的只读属性的类型?

typescript - 是否可以为多类型参数类/函数的多个参数创建类型别名?

angular - 公共(public)或私有(private) - Angular 2 组件类方法混淆

javascript - TypeScript 的方法别名

typescript - 无法重新声明 block 作用域变量

typescript - 为什么条件类型中的 "infer"会改变返回类型?

typescript - Typescript 泛型中的 "Not in keyof"

c# - Visual Studio : "Learn this keyboard shortcut" recommendation?

javascript - 如何使用vendors.ts构建的库并通过webpack导入一次?

typescript - TypeScript 如何推断回调参数类型