typescript:定义类集合的类型

Posted

技术标签:

【中文标题】typescript:定义类集合的类型【英文标题】:typescript: define the type of a classes collection 【发布时间】: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

谢谢。

【问题讨论】:

【参考方案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

【讨论】:

以上是关于typescript:定义类集合的类型的主要内容,如果未能解决你的问题,请参考以下文章

Typescript Interfaces(接口)添加任意key值/内容

转载:TypeScript 简介与《TypeScript 中文入门教程》

在 TypeScript 中获取类方法的名称

如何在 Jest 的自定义测试环境文件中使用 TypeScript?

TypeScript(15): 接口

当没有要指定的确切值“未定义”或“空”时,为 TypeScript 可选参数传递啥? [复制]