简体   繁体   中英

Strongly typed Immutable.js Records in TypeScript

I'm unable to find a good resource for this question. Essentially I want to describe types for my data using an interface in TypeScript, but my data is Immutable.js records which appears to complicate matters, please see my example below.

interface tree extends Immutable.Map<string, any> {
  readonly id: number,
  readonly type: number
}

let trees = Immutable.List<tree[]>([
  Map<tree>({
     id: 101,
     type: 1
  }),
  Map<tree>({
     id: 201,
     type: 3
  })
])

Questions with the above:

  1. Why do I have to repeat the type of each map in my list? Shouldn't the type be simply be declared by the <tree[]> when creating the list? And then any Map added to the list be type checked against this?
  2. At present this example errors, stating that "property 'id' is incompatible with index signature. Type 'number' is not assignable to type 'tree'. Which makes sense! However, reading the documentation, I can't work out how to get it to work? Reading the docs it states I need an ID but I want an array of maps, my signature in this case is just standard array ID's if I not much mistaken?

I've been working on this for days and I simply can't get it to work, it should be this simple according to everything I've read.

Any help would be greatly appreciated.

You are creating a List of arrays of trees , which is an extended Map . This is what it should look like:

let trees = Immutable.List<tree[]>(
    [ // List
        [ // Array
            <tree>Immutable.Map<any>({
                id: 101,
                type: 1
            }),
            <tree>Immutable.Map<any>({
                id: 201,
                type: 3
            })
        ]
    ]
);

Answering your questions:

  1. You are not repeating the type of each map. Actually, you are calling a method Map that builds a map from an object. I added the <tree> cast because it is an array of trees , not maps.
  2. You are trying something like:

     var singleTree: tree = Immutable.Map<tree>( { id: 101, type: 1 } ); 

    But your tree is a map of the any type. So, this is the right syntax:

     let singleTree: tree = <tree>Immutable.Map<any>( { id: 101, type: 1 } ); 

For the code above, we can simplify and force a type check if we create a tree function to wrap the Map function, so, the final solution would be:

function tree(obj: { [key: string]: any, id: number, type: number }): tree {
    return <tree>Immutable.Map<any>(obj);
}

let trees = Immutable.List<tree[]>(
    [ // List
        [ // Array
            tree({
                id: 101,
                type: 1
            }),
            tree({
                id: 201,
                type: 3
            })
        ]
    ]
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM