Я портирую приложение Javascript на Typescript.У меня есть объект со многими свойствами массива, содержащими данные, и функция JavaScript делает доступ к массивам данных.Для простоты я рассматриваю только метод add
function updateDataStructure(state, structureName, elem) {
state.data[structureName].push(elem);
return state.data[structureName];
}
Портирование на машинописный текст Я хотел бы ввести безопасность типов и поддерживать универсальный код.
interface AA {
lep: string,
snap: number,
sul: boolean
}
interface BB {
p1: string;
val: number;
}
interface StateDataContainer {
aa: AA[],
bb: BB[],
}
class State {
data: StateDataContainer;
}
export type DataContainerProps = keyof StateDataContainer;
type ArrayElement<ArrayType> = ArrayType extends (infer ElementType)[] ? ElementType : never;
function updateDataStructure<K extends DataContainerProps, D extends ArrayElement<StateDataContainer[K]>>
(state: State, structureName: K, elem: D)
: StateDataContainer[K] {
// @ts-ignore
state.data[structureName].push(elem);
return state.data[structureName];
}
С этим кодом у меня есть типизированный сейфИнтерфейс, компилятор проверяет клиентский код, чтобы добавить правильные объекты в правильную структуру.
const state = new State();
let avv: BB;
let line: AA;
let v: BB[] = updateDataStructure(state, 'bb', avv!);
let l: AA[] = updateDataStructure(state, 'aa', line!);
с этим решением я должен добавить использовать аннотацию // @ ts-ignore в коде реализации, чтобы избежать компилятораошибки вроде:
Argument of type 'D' is not assignable to parameter of type 'AA & BB'.
Type 'ArrayElement<StateDataContainer[K]>' is not assignable to type 'AA & BB'.
Type '{}' is not assignable to type 'AA & BB'.
Type '{}' is not assignable to type 'AA'.
Type 'AA | BB' is not assignable to type 'AA & BB'.
Есть ли лучший подход для написания этого кода?