typescript:定义类集合的类型

时间:2017-03-29 13:35:14

标签: object typescript collections types

我不知道如何用打字稿定义班级集合的类型:

当我编译以下代码时,我遇到了错误:

    class Wall{
        brick: string;

        constructor(){
            this.brick = "jolies briques oranges";
        }

        // Wall methods ...
    }

class Critter {
    CritterProperty1: string[];
    CritterProperty2: string;

    constructor() {
        this.CritterProperty1 = "n ne e se s so o no".split(" ");        
    }

    // Critter methods ...
}

type legendObjectType = Critter | Wall;

interface Ilegend {
    [k: string]: legendObjectType; 
}

// i've got an issue to define the type of 'theLegend' Object
let theLegend: Ilegend = {
    "X": Wall,
    "o": Critter
}
  

错误TS2322:键入' {" X":typeof Wall; " o":typeof Critter; }'不是   可归类为' Ilegend'。

虽然我可以编译它,如果"类墙"是空的。

有谁知道如何定义这类课程的类型?

  

让theLegend = {       " X":墙,       " o":小动物}

(这是eloquent javascript第7章的例子,而不是我试图在打字稿中转录)

修改

我完成了Rico Kahler的答案,使用抽象类来避免使用联合类型

abstract class MapItem {
    originChar: string;

    constructor(){}
}

class Wall extends MapItem {
    brick: string;

    constructor(){
        super();
        this.brick = "jolies briques oranges";
    }

    // Wall methods ...
}

class Critter extends MapItem {
    CritterProperty1: string[];
    CritterProperty2: string;

    constructor() {
        super();
        this.CritterProperty1 = "n ne e se s so o no".split(" ");        
    }

    // Critter methods ...
}

interface Ilegend {
    [k: string]: new () => MapItem; 
}

let theLegend: Ilegend = {
    "X": Wall,
    "o": Critter
}

感谢' S

1 个答案:

答案 0 :(得分:1)

您的问题在于您的对象theLegend

Typescript需要一个Wall或Critter的实例,而是你为它提供一个类型。

let theLegend: Ilegend = {
    "X": Wall, // `Wall` is a type not an instance, it is `typeof Wall` or the Wall type
    "o": Critter // `Criter` is a type not an instance
}

以下内容将起作用:

let theLegend: Ilegend = {
    X: new Wall(), // now it's an instance!
    o: new Critter()
}

修改

现在阅读你链接的javascript页面,似乎我错过了你的意图。如果你想创建一个接受构造函数的接口,那么我将按如下方式键入Ilegend

interface Legend {
    [k: string]: new () => (Critter | Wall)
}

// now you can define an object with this type

let legend: Legend = {
    // here `Critter` actually refers to the class constructor
    // that conforms to the type `new () => (Critter | Wall)` instead of just a type
    something: Critter,
    somethingElse: Wall
}

const critter = new legend.something() // creates a `Critter`
const wall = new legend.somethingElse() // creates a `Wall`

// however, the type of `critter` and `wall` are both `Critter | Wall`. You'd have to use type assertion (i.e. casting) because typescript can't tell if its either a Critter or a Wall

现在接口允许任何字符串成为键,并且它希望每个值都是一个函数,您可以调用new来获取CritterWall