TypeScript | Immutable | proper way to extend Immutable.Map type

I have a response-redux application written in typescript with an immutable package. There I have data that comes from the api and in the store I pack it into Map. In all applications they are used as a map.

I created an interface:

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

In general, it works very well. Other than tests, where I create data this way:

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

and then I get lint error:

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

I feel completely lost since I can see the id in the interface and in my dummy data.

I would take care of him. I feel that somehow I have to pass a list of acceptable keys to my Card, but I don’t know how to do it.

EDIT: misspell

+2
source share
1 answer

( ):

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

Immutable.js, (T[K]). AFAIK , get.

EDIT: 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`


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 . Map, Object. fromJS over Map , .

: Record s.

+5

Source: https://habr.com/ru/post/1693267/


All Articles