我想为我的对象使用不可变的js,这是代码:
import {User} from "../../models/user";
import {Map} from "immutable";
export interface State extends Map<string, any> {
user: User,
token: string,
};
const initialState: State = Map<string, any>({
user: null,
token: null,
});
但我有这个错误:
Error:(11, 7) TS2322:Type 'Map<string, any>' is not assignable to type 'State'.
Property 'user' is missing in type 'Map<string, any>'.
我该如何解决?
答案 0 :(得分:2)
Map
对象不包含user
和token
属性,因此无法将其分配给State
类型。因此,在使用Map
时会丢失静态类型。
我强烈建议您使用Record而不是Map:
export interface IState {
user: User,
token: string,
}
export const State = Immutable.Record<IState>({
user: null,
token: null
});
const initialState = new State();
let state = initialState.set('token', '123');
let token = state.get('token');
不幸的是,来自Facebook的类型定义有点不对,但如果添加Readonly<T>
声明,则只需阅读state.token
属性:
export interface Instance<T extends Object> {
...
set<K extends keyof T>(key: K, value: T[K]): this & Readonly<T>;
update... : this & Readonly<T>;
...
}
More关于记录。
答案 1 :(得分:2)
我最近花了一些时间来解决这个问题。虽然我发现大多数答案建议切换到Records,但我正在做一个大型重构,并且不想更新相当大的代码库中的所有数据结构。
经过大量搜索,我发现这个github问题得到了我正在寻找的答案: https://github.com/facebook/immutable-js/issues/683#issuecomment-381089789(见最后评论。)
基本上,您扩展基本的immutable.Map接口以接受特定情况的类型定义。
对于您的具体情况,它看起来像这样:
import {User} from "../../models/user";
import {Map} from "immutable";
// The default Map interface accepts <K,V>: Key, Value.
// Build an interface that also accepts 'T': the shape of your data.
export interface IImmutableMap<T, K, V> extends Map<K, V> {
toJS(): T;
get<I extends keyof T>(key: I & K): T[I] & V;
set<S extends keyof T>(key: S & K, value: T[S] & V): Map<K, V>;
}
// Extend Map to define the shape of your data
export interface IState extends Map<string, any> {
user: User,
token: string,
};
// Pass the shape to your new interface to define a type.
export type TState = IImmutableMap<IState, string, any>;
// Update the type definition on initial state to your type.
const initialState: TState = Map<string, any>({
user: null,
token: null,
});
您可以通过为每个特定案例创建新的接口和类型定义,在整个代码库中重用此IImutableMap接口。
如果您需要为其他immutable.js数据结构创建接口,那么不可变文档将是无价的:https://facebook.github.io/immutable-js/docs/#/
这是一个简短的博客,解释了为什么您可能选择不使用记录数据结构: https://blog.mayflower.de/6630-typescript-redux-immutablejs.html