【问题标题】:typescript: define the type of a classes collectiontypescript:定义类集合的类型
【发布时间】:2017-08-23 00:49:32
【问题描述】:

我不知道如何在 typescript 中定义类的集合类型:

当我编译以下代码时,出现错误:

    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: Type '{ "X": typeof Wall; “o”:Critter 的类型; }' 不是 可分配给类型“Ilegend”。

虽然我可以编译它,但如果“班级墙”是空的。

有人知道如何定义此类集合的类型吗?

让传奇 = { “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
}

谢谢。

【问题讨论】:

    标签: object typescript collections types


    【解决方案1】:

    你的问题在于你的对象theLegend

    Typescript 期望是 Wall 或 Critter 的 instance,但您为它提供了一个类型。

    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

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 2019-04-01
      • 2016-06-22
      相关资源
      最近更新 更多