4
votes

I have few classes. Test~ classes extend FrameModel.

How can I create a map from string to subclasses of FrameModel?

import FrameModel from '../../FrameModel';
import TestShipModel from './TestGeneratorModel';
import TestGeneratorModel from './TestGeneratorModel';
import TestPlanetModel from './TestGeneratorModel';

export class DiscriminatorMappingData
{
    static mapping: { [key: string]: typeof FrameModel } = {
        "TestShip": TestShipModel,
        "TestGenerator": TestGeneratorModel,
        "TestPlanet": TestPlanetModel,
    }
}

This ends up with an error:

DiscriminatorMappingData.ts(8,5): error TS2322: Type '{ [x: string]: typeof "...' is not assignable to type '{ [key: string]: typeof "...'.
Index signatures are incompatible.
Type 'typeof "...models/T...' is not assignable to type 'typeof ".../FrameModel"'.
Property 'FrameModel' is missing in type 'typeof ".../models/T...'.

I assume this can be done with generics but I'm not sure how.

2
Are you missing curly brackets for import e.g. import {FrameModel} from ...CuriousMind
Looks like that was the problem! You may put it as answer.Ondra Žižka
Added as an answer, please accept it. Thanks.CuriousMind
It's a bit weird "solution", I had to think which answer to accept. but thanks for noticing :)Ondra Žižka
You are right Ondra, in fact it is the same reason, I added it first as a comment :) There was nothing like a solution, just identifying the syntax problem. But I am glad, if that has saved your time. The other approach that has been proposed, will have one limitation of defining all the relevant classes in one file. While the syntax mistake that I spotted, will help you to split definitions across the files (I guess, you had same intention too). But anyways you are free to choose the correct answer and approach.CuriousMind

2 Answers

3
votes

You can declare hashtable with type of base class (FrameModel) and use descendant types as real values (I've omitted modules for simplicity):

class FrameModel {
}

class TestShipModel extends FrameModel {
}
class TestGeneratorModel extends FrameModel {
}
class TestPlanetModel extends FrameModel {
}

export class DiscriminatorMappingData
{
    static mapping: { [key: string]: typeof FrameModel } = {
        "TestShip": TestShipModel,
        "TestGenerator": TestGeneratorModel,
        "TestPlanet": TestPlanetModel,
    }
}

This code works for me in the Typescript playground.

1
votes

(With reference to the comment, here is the solution to the problem.)

The problem seems to be with the import statement and curly brackets should be included while importing class. e.g. import {FrameModel}...