У меня есть такая функция:
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>>;
so
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 так себя ведет?
T
равно{id: "stringLiteralValue"}
, тогдаT
можно назначить{id: string}
, но не наоборот < / i>. Только вы знаете, заботитесь ли вы об этих крайних случаях.) - person jcalz   schedule 14.03.2019as Array<T>
после возврата ошибки компиляции исчезнут. Но почему TS считает, чтоOmit<T, 'key'> & {key: string}
не совсем то же самое, чтоT
. Особенноid
атрибут должен существовать в типеT
- person Przemyslaw Jan Beigert   schedule 14.03.2019T
равно{id: "stringLiteralValue"}
,T
может быть назначен{id: string}
, но{id: string}
не может быть назначенT
. Они не одного типа. - person jcalz   schedule 14.03.2019as Array<T>
(спасибо!). Но мне все еще интересно, почему TS не рассчитал новый тип. Тем более что Omit ‹T, 'id'› нужно было вычислить, а оператор&
вычислить довольно просто. - person Przemyslaw Jan Beigert   schedule 14.03.2019