2017-04-25 2 views
1

불변의 패키지로 typescript로 작성된 react-redux 애플리케이션이 있습니다. 거기에 API에서 오는 데이터가 있고 상점에서지도에 저장합니다. 모든 어플리케이션에서 Map으로 사용됩니다. 일반적으로TypeScript | 변경 불가능 | Immutable을 확장하는 적절한 방법. Map type

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

이 아주 좋은 작동합니다

나는 인터페이스를 만들었습니다. 내가 데이터를 이런 식으로 만들 테스트, 제외 :

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를 볼 수있는 나는 완전히 잃어버린 느낌 :

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

후 나는 린트 오류가 발생합니다.

감사합니다. 어떻게 든 맵에 수용 할 수있는 키 목록을 전달해야한다고 생각합니다.

편집 : 우리는 우리의 프로젝트에서이처럼 사용 (약간 다른 접근 방식을)

답변

4

를 잘못 입력 :

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

우리는 아직 매핑 유형을 사용하지 않은 Immutable.js typings의 이전 버전을 사용 (T[K]). 그 이후 AFAIK 입력 내용이 업데이트되어 get 메서드를 덮어 쓸 필요가 없습니다.

편집 실제로는 get 메서드는 위와 달리 완전히 형식이 안전하지 않습니다. 그래서이 방법을 덮어 쓰는 것은 여전히 ​​장점이 있습니다. 위의 선언으로

당신은 다음과 같은 불변의 맵을 만들 수 있습니다

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

const authState:AuthState = fromJS({ user: 'Alice', loggedIn: true }); 
이상적으로

, 당신은이 같은 typings 싶습니다 :

/** 
* 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


을 내가 예에서 fromJS을 사용

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

참고 : 누구의 유일한 목적 typings을 "수정"하는 작은 도우미 함수를 만들 수 있습니다 Immutable.js으로 위를 달성하기 위해

. 전달 된 입력이 Object 인 경우 Map이 생성됩니다. fromJSMap 이상으로 사용하면 입력 한 내용을 덮어 쓰기가 쉽습니다.

사이드 노트 : Record을 살펴볼 수도 있습니다.

+1

감사합니다. 귀하의 답변에서 매우 유용한 정보를 얻었습니다. – Kania

+0

이것은'Record' (그냥'get'과 함께)에도 적용됩니까? – ton