object - typescript :定义类集合的类型

标签 object typescript collections types

我不知道如何在 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
}

error TS2322: Type '{ "X": typeof Wall; "o": typeof Critter; }' is not assignable to type 'Ilegend'.

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

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

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

(这是 eloquent javascript 的第 7 章的一个例子,我试着用 typescript 抄录)

编辑

我用一个抽象类来完成 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
}

谢谢。

最佳答案

您的问题在于您的对象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 页面,似乎我没有理解您的意图。如果您想创建一个采用构造函数的接口(interface),那么我将按如下方式键入 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

现在接口(interface)允许任何字符串作为键,它希望每个值都是一个函数,您可以调用 new 来获取 Critter

关于object - typescript :定义类集合的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43095091/

相关文章:

javascript - 如何检查包含另一个对象数组的对象数组是否具有属性

javascript - Angular Typescript - 从数组返回满足约束的对象数量

node.js - 在 TypeScript 中创建 swagger web 服务的正确方法是什么

angular - 单元测试将类动态添加到 HTML 按钮 Jasmine

xml - JAXB:如何围绕 XmlRootElement 添加包装器?

php - 我该如何回应这个?

javascript - 为嵌套 json 运行 for every 循环

javascript - 将新对象插入循环中的现有对象中

java - Map.get(Object key) 不是(完全)通用的原因是什么

C#线程图像处理