gpt4 book ai didi

typescript |不可变 |扩展 Immutable.Map 类型的正确方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:16:37 27 4
gpt4 key购买 nike

我有一个用 typescript 编写的带有不可变包的 react-redux 应用程序。我有一个数据,它来自 api 并且在存储中我将它打包到 Map 中。在所有应用程序中,它们都用作 map 。

我创建了一个界面:

export interface PaymentMethod extends Immutable.Map<string, string | NamedType<number>> {
id: string;
name: string;
description: string;
accountNr: string;
paymentMethodType: NamedType<number>;
}

总的来说效果很好。除了测试,我以这种方式创建数据:

const dummyPaymentMethod: PaymentMethod = Map({
id: '',
name: '',
description: '',
accountNr: '',
paymentMethodType: { id: 1, name: '' },
});

然后我得到一个 lint 错误:

Error:(116, 13) TS2322:Type 'Map<string, string | { id: number; name: string; }>' is not assignable to type 'PaymentMethod'.
Property 'id' is missing in type 'Map<string, string | { id: number; name: string; }>'.

我感到完全迷失了,因为我可以在界面和我的虚拟数据中看到 id。

我将不胜感激。我觉得我应该以某种方式将可接受的键列表传递给我的 map ,但不知道如何执行此操作。

编辑:拼写错误

最佳答案

我们在项目中这样使用它(方法略有不同):

interface ImmutableMap<T> extends Map<string, any> {
get<K extends keyof T>(name: K): T[K];
}

我们使用了尚未使用映射类型的旧版本 Immutable.js (T[K])。从那时起更新了 AFAIK 类型,无需覆盖 get 方法。

编辑:实际上 get 方法与上面不同,它仍然不是完全类型安全的。所以重写方法还是有好处的。

通过上面的声明,您可以创建不可变映射,例如:

type AuthState = ImmutableMap<{
user:string|null;
loggedIn:boolean;
}>;

const authState:AuthState = fromJS({ user: 'Alice', loggedIn: true });

理想情况下,您希望这样输入:

/**
* Imaging these are typings for your favorite immutable
* library. We used it to enhance typings of `immutable.js`
* with the latest TypeScript features.
*/
declare function Immutable<T>(o: T): Immutable<T>;
interface Immutable<T> {
get<K extends keyof T>(name: K): T[K];
set<S>(o: S): Immutable<T & S>;
}

const alice = Immutable({ name: 'Alice', age: 29 });
alice.get('name'); // Ok, returns a `string`
alice.get('age'); // Ok, returns a `number`
alice.get('lastName'); // Error: Argument of type '"lastName"' is not assignable to parameter of type '"name" | "age"'.

const aliceSmith = alice.set({ lastName: 'Smith' });
aliceSmith.get('name'); // Ok, returns a `string`
aliceSmith.get('age'); // Ok, returns a `number`
aliceSmith.get('lastName'); // Ok, returns `string`

Link to the Playground


为了使用 Immutable.js 实现上述目标,您可以创建一个小的辅助函数,其唯一目的是“修复”类型:

import { fromJS } from 'immutable';

interface Immutable<T> {
get<K extends keyof T>(name: K): T[K];
set<S>(o: S): Immutable<T & S>;
}

function createImmutable<T extends object> (o:T) {
return fromJS(o) as Immutable<T>;
}

请注意,我在示例中使用了 fromJS。只要传递的输入是一个 Object,这就会创建一个 Map。使用 fromJS 而不是 Map 的好处是类型更容易被覆盖。

旁注:您可能还想查看 Record

关于 typescript |不可变 |扩展 Immutable.Map 类型的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43607652/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com