Я пишу конвертер, который преобразует массив кортежей в объект, используя объект поиска, который сообщает функции, какие строки соответствуют каким свойствам. Тем не менее, я не могу найти способ сказать машинописи, что это массив кортежей с указанными c типами, результирующие кортежи всегда являются объединениями. Вот как это выглядит:
interface EndObj {
a: number;
b: string;
c?: number;
}
interface InitObj {
d: string;
e: string;
f: string;
}
const map = {
d: 'a',
e: 'b',
f: 'c'
} as const;
type MapType = typeof map;
type ResultTuple<T extends keyof InitObj> = [T, EndObj[MapType[T]]];
type ResultTupleArray = ResultTuple<keyof InitObj>[];
const resultObj: ResultTupleArray = [['d', 1], ['e', 3], ['f', 3]]; // invalid! the value of 'e' should only allow strings
Думаю, причина, по которой машинопись позволяет это, заключается в том, что ResultTupleArray
определяется с помощью keyof InitObj
, поэтому результирующий массив кортежей generi c всегда одинаков, так что T
всегда будет одинаковым вместо спецификаций c для каждой записи массива, поэтому его можно описать только с помощью объединения.
Вот как я это выяснил:
const undetected: ResultTuple<keyof InitObj> = ['e', 4]; // should be invalid
const detected: ResultTuple<'e'> = ['e', 4]; // actually shows an error for 4 (Type 'number' is not assignable to type 'string'.)
Для некоторого контекста, вот как выглядит конвертер:
function mapInitToEnd(resultO: ResultTupleArray) {
const endObj: EndObj = {
a: -1,
b: ''
};
for (const tuple of resultO) {
const [key, val] = tuple;
const mappedKey = map[key];
endObj[mappedKey] = val;
}
return endObj;
}
Есть ли способ сказать машинописи, что generic c действителен только для каждой записи в массиве кортежей, а не для полный массив?