我花了很多时间在这上面,我会很感激一些帮助。我想要一个组件(一个函数)接受一个对象数组,同时还验证对象的属性。
接口(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/