#typescript #types
#typescript #типы
Вопрос:
У меня есть два типа, которые разделяют подмножество свойств, например
type A = {
x: number
y: number
desc: string
}
type B = {
x: number
y: number
address: number
}
Я хотел бы иметь только одну функцию, которая может что-то делать с этими типами, читая только некоторые реквизиты:
const munge = <T>(list: T[]): T[] => list.sort((a,b) => a.x - b.x)
Очевидно, что это не работает (ошибка Property 'x' does not exist on type 'T'.
), даже если я пытаюсь использовать munge
на A[]
(таким образом, я узнаю, что обобщения не работают как шаблоны C ).
Я понимаю, что это может быть ограничением языка, но что я вообще могу здесь сделать? Должен ли я специально определять munge в терминах типов A и B или какого-либо другого типа, который является их подмножеством? Дело в том, что я хотел бы иметь возвращаемый тип be T[]
, то есть, если я отправлю в B[]
to munge
, я бы хотел, чтобы typescript понимал, что munge в этом случае вернет обратно a B[]
. Казалось бы, если я munge
явно определю, чтобы принять A или B (или его пока еще неписаный базовый тип C
, имеющий только x
prop), позже будет больше уродства при приведении его обратно к любому типу, в который он вошел munge
как.
Например, было бы неприемлемо, чтобы мне нужно было написать две реализации munge
, одну taking A[]
и одну taking B[]
. Правда ли, что это единственный практичный чистый способ сделать это? (это не чисто)
Ответ №1:
Пока этот код кажется достаточно простым для чтения и выполняет свою работу. Хотя мне это не нравится.
type A = {
x: number;
desc: string;
};
type B = {
x: number;
addr: number;
};
type C = {
x: number;
};
const munge = <T extends C>(list: T[]): T[] => list.sort((a, b) => a.x - b.x);
const aa: A[] = [
{ x: 5, desc: "a" },
{ x: 0, desc: "" },
];
console.log(aa);
const z = munge(aa);
// editor shows type of z is A[]. I'm satisfied...
console.log(z);
Комментарии:
1. Это ответ. Структурная типизация может быть не слишком удобной для тех, кто использует более жесткую систему типов, но это естественный способ выразить это в TS.