如何将 TypeScript 类型安全添加到我的 redux 操作中? [英] How to add TypeScript type safety to my redux action?

查看:42
本文介绍了如何将 TypeScript 类型安全添加到我的 redux 操作中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 TypeScript 编写我的应用程序,并且我正在使用 Redux 来跟踪我的应用程序状态.我的 redux 存储状态如下所示:

I'm writing my application in TypeScript and I'm using Redux to keep track of my app state. My redux store state looks something like this:

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 函数并不理想,因为它没有类型安全!

I created the following action to let me update the store however the setPropertyValue function is not ideal since it has no type safety!

//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;
  };
}

我可以这样在我的代码中使用这个动作:

I can use this action in my code this way:

setPropertyValue( ['grid', 'extents'], 100 );

这是可行的,但是由于 setPropertyValue 函数中没有类型安全性,因此没有什么可以限制我将无效值输入到函数中,如下所示:

This works, but since there is no type safety in the setPropertyValue function there is nothing restricting me from feeding invalid values into the function like this:

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 中找到的属性名称有效的参数.此外,传入的值必须与所选属性的正确类型相对应.

Is there a way to rewrite the setPropertyValue function so that it only accepts arguments that are valid for the property name found in AppState. Also the value passed in must correspond to the correct type for the selected property.

也许使用字符串数组来更改 属性 并不理想,但我不知道有什么更好的方法可以仅定位 AppState 中可用的属性.

Perhaps using a string array for the property to change is not ideal but I don't know of a better way to target only the properties that are available in AppState.

推荐答案

如果您需要索引签名,则无法验证该类型的键(因为毕竟索引签名意味着该类可被任何键,所以任何键都是有效的)

If you need the index signature then there is no way to validate the keys of the type (since after all the index signature would mean the class in indexable by any key, so any key would be valid)

要验证字符串是否为某个类型的键,我们可以使用 keyof 运算符,并结合一些通用类型参数(以捕获传入的实际键)

To validate taht a string is a key of a type we can use the keyof operator, in conjuction with some generic type parameters (to capture the actual key passed in)

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;
}

const setPropertyValue = <KApp extends keyof AppState, KAppProp extends keyof AppState[KApp]>( property : [KApp, KAppProp], value : AppState[KApp][KAppProp] ) : SetPropertyValueAction => ( {
  type: 'SET_PROPERTY_VALUE',
  payload: {
    property,
    value,
  }
} );

interface SetPropertyValueAction {
  type : string;
  payload : {
    property : PropertyKey[];
    value : any;
  };
}

setPropertyValue( ['grid', 'extents'], 100 );
setPropertyValue( ['grid', 'size'], 100 ); //err
setPropertyValue( ['grid', 'isXY'], -1 ); //err
setPropertyValue( ['selected', 'bodyColor'], '255' );// err 

这篇关于如何将 TypeScript 类型安全添加到我的 redux 操作中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆