Я пишу свое приложение на TypeScript и использую Redux для отслеживания состояния моего приложения. Состояние моего магазина редуксов выглядит примерно так:
interface AppState {
readonly grid : IGridSettings;
readonly selected : ISelectedSettings;
[key : string] : IGridSettings | ISelectedSettings;
}
interface IGridSettings {
readonly extents : number;
readonly isXY : boolean;
readonly isXZ : boolean;
readonly isYZ : boolean;
readonly spacing : number;
[key : string] : number | boolean;
}
interface ISelectedSettings {
readonly bodyColor : number;
readonly colorGlow : number;
readonly lineColor : number;
readonly selection : number[] | undefined;
[key : string] : number | number[] | undefined;
}
Я создал следующее действие, чтобы позволить мне обновить магазин, однако функция setPropertyValue не идеальна, так как не имеет безопасности типов!
//How to add type safety to this function?
const setPropertyValue = ( property : string[], value : any ) : SetPropertyValueAction => ( {
type: 'SET_PROPERTY_VALUE',
payload: {
property,
value,
}
} );
interface SetPropertyValueAction extends Action {
type : string;
payload : {
property : string[];
value : any;
};
}
Я могу использовать это действие в своем коде следующим образом:
setPropertyValue( ['grid', 'extents'], 100 );
Это работает, но, поскольку в функции setPropertyValue нет безопасности типов, ничто не ограничивает меня от ввода недопустимых значений в функцию, например:
setPropertyValue( ['grid', 'size'], 100 ); //invalid since IGridSettings doesn't have a 'size' property
setPropertyValue( ['grid', 'isXY'], -1 ); //value should be a boolean not a number
setPropertyValue( ['selected', 'bodyColor'], '255' ); //value should be a number not a string
Есть ли способ переписать функцию setPropertyValue, чтобы она принимала только те аргументы, которые действительны для имени свойства, найденного в AppState . Также переданное значение должно соответствовать правильному типу для выбранного свойства.
Возможно, использование строкового массива для свойства для изменения не является идеальным, но я не знаю лучшего способа нацеливания только на свойства, доступные в AppState.