我有这样的功能:
const createRelationship = <T extends { id: string }>(
includedItems: Array<DataResponse<T>>,
categories: Array<{ id: string, type: string }>,
): Array<T> => {
return categories.map(({ id }) =>
includedItems.find((includedItem) => includedItem.id === id) as DataResponse<T>)
.map(flatAttributes);
};
它采用通用类型T。第一个参数是DataResponse数组,其中:
interface DataResponse<T extends { id: string }, R = void> {
id: string;
attributes: Omit<T, 'id'>;
}
和:
type Omit<A extends object, K extends keyof A> = Pick<A, Exclude<keyof A, K>>;
如此
type Example = DataResponse<{ id: string, key: number }> // { id: string, attributes: { key: number } };
函数flatAttributes
如下所示:
const flatAttributes = <T extends { id: string, attributes: any }>(item: T): { id: string } & T['attributes'] =>
({...item.attributes, ...item });
这是一种反向操作,例如:
flatAttributes{ id: string, attributes: { key: number } }) === { id: string, key: number }
现在为止:createRelationship
的汇编:
Type '({ id: string; } & Pick<T, Exclude<keyof T, "id">>)[]' is not assignable to type 'T[]'.
Type '{ id: string; } & Pick<T, Exclude<keyof T, "id">>' is not assignable to type 'T'.
Pick<T, Exclude<keyof T, "id">>'
是Omit<T, 'key'>
,而Omit<T, 'key'> & {key: string}
应该是相同的T
。
任何想法如何在不安全映射的情况下声明此函数?为什么TypeScript会表现得如此?