TypeScript:如何强制转换通用对象? [英] TypeScript: How to cast a generic object?
问题描述
我有以下接口:
interface AppState {
readonly grid : IGridSettings;
readonly selected : ISelectedSettings;
}
interface IGridSettings {
readonly extents : number;
readonly isXY : boolean;
readonly isXZ : boolean;
readonly isYZ : boolean;
readonly spacing : number;
}
interface ISelectedSettings {
readonly bodyColor : number;
readonly colorGlow : number;
readonly lineColor : number;
readonly selection : number[] | undefined;
}
interface Action<T = any> {
type: T
}
interface SetPropertyValueAction<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]> extends Action {
type : string;
payload : {
property : [KAction, KActionProp];
value : IUserActions[KAction][KActionProp];
};
}
最终,在发出setPropertyValue函数时,我的redux reducer会被调用:
Eventually my redux reducer gets called when the setPropertyValue function is emitted:
const setPropertyValue = <KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>( property : [KAction, KActionProp], value : AppState[KAction][KActionProp] ) : SetPropertyValueAction<KAction, KActionProp> => ( {
type: 'SET_PROPERTY_VALUE',
payload: {
property,
value,
}
} );
function myReducer( state : AppState = INITIAL_STATE, a : Action ) : AppState {
switch( a.type ) {
case 'SET_PROPERTY_VALUE': {
const action = a as SetPropertyValueAction; // <- error here
return createNewState( state, action.payload.property, action.payload.value );
}
}
return states;
}
我遇到的问题是我不知道如何解决从Action到SetPropertyValueAction的转换。 TypeScript告诉我错误是:
The problem that I'm having is I don't know how to fix the cast from Action to SetPropertyValueAction. TypeScript tells me the error is:
Generic type 'SetPropertyValueAction<KAction, KActionProp>' requires 2 type argument(s).
我尝试将有错误的代码行更改为以下内容:
I tried changing the line of code that has the error to the following:
const action = a as SetPropertyValueAction<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>;
...但这给了我两个错误,说找不到名称KAction和KActionProp
...but this gives me two errors saying 'Cannot find name KAction and KActionProp'
如何将Action对象转换为通用SetPropertyValueAction?
How can I cast an Action object to the generic SetPropertyValueAction ??
这是我其他问题的后续问题此处已回答的问题:如何添加TypeScript类型安全性到我的redux动作?
This is a follow up question to my other question that has been answered here: How to add TypeScript type safety to my redux action?
推荐答案
我们需要为该类型指定类型参数。由于我们并不真正了解它们,因此我们需要与T $$$的 key兼容的东西,但不是
T $ c的实际钥匙。 $ c>。
未知
不会执行,因为它不满足约束,我们可以使用的一种类型是 any
或从不
(它是任何类型的子类型)
We need to specify the type parameters for the type. Since we don't really know them, we need something that is compatible with keyof T
but represent is not an actual key of T
. unknown
will not do since it does not satisfy the constraint, the one type we can use is any
or never
(which is a subtype of any type)
interface AppState {
readonly grid: IGridSettings;
readonly selected: ISelectedSettings;
}
interface IGridSettings {
readonly extents: number;
readonly isXY: boolean;
readonly isXZ: boolean;
readonly isYZ: boolean;
readonly spacing: number;
}
interface ISelectedSettings {
readonly bodyColor: number;
readonly colorGlow: number;
readonly lineColor: number;
readonly selection: number[] | undefined;
}
interface Action<T = any> {
type: T
}
interface SetPropertyValueAction<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]> extends Action {
type: string;
payload: {
property: [KAction, KActionProp];
value: AppState[KAction][KActionProp];
};
}
const setPropertyValue = <KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>(property: [KAction, KActionProp], value: AppState[KAction][KActionProp]): SetPropertyValueAction<KAction, KActionProp> => ({
type: 'SET_PROPERTY_VALUE',
payload: {
property,
value,
}
});
declare const INITIAL_STATE: AppState;
// implementation if necessary
function createNewState<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>(state: AppState, property: [KAction, KActionProp], value: AppState[KAction][KActionProp]): AppState {
return Object.assign({ ...state }, {
[property[0]]: Object.assign({ ...state[property[0]] }, {
[property[1]]: value,
})
});
}
function myReducer(state: AppState = INITIAL_STATE, a: Action): AppState {
switch (a.type) {
case 'SET_PROPERTY_VALUE': {
const action = a as SetPropertyValueAction<never, never>; // we don't know the actual type, never will have to do
return createNewState(state, action.payload.property, action.payload.value);
}
}
return state;
}
这篇关于TypeScript:如何强制转换通用对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!