【问题标题】:How does TypeScript know about the behaviour of the length field in custom array types?TypeScript 如何知道自定义数组类型中长度字段的行为?
【发布时间】:2017-03-11 10:21:05
【问题描述】:

当您使用接口创建自定义数组类型并为其提供字段length: number 时,TypeScript 似乎以某种方式自行计算数组的长度,但如果您将字段排除在自定义类型定义之外,它不再有效。

这里到底发生了什么?

我的代码是:

interface IPerson {
    fullName: string;
    age: number;
}

class Person implements IPerson {
    fullName: string;
    age: number;

    constructor(fullName: string, age: number) {
        this.fullName = fullName;
        this.age = age;
    }
}

interface IPersonArray {
    [index: number]: IPerson;
    length: number;
}

var personArray: IPersonArray = [new Person("Jane", 21),
                                new Person("John", 22)];

for (var i = 0; i < personArray.length; i++) {
    console.log(personArray[i].fullName);
}

这是最相关的部分:

interface IPersonArray {
    [index: number]: IPerson;
    length: number;
}

var personArray: IPersonArray = [new Person("Jane", 21),
                                new Person("John", 22)];

for (var i = 0; i < personArray.length; i++) {
    console.log(personArray[i].fullName);
}

我只是在界面中声明了length 字段,但是 TypeScript 神奇地找出了长度字段应该如何工作,并且我得到了预期的输出。这是怎么发生的?

【问题讨论】:

    标签: arrays typescript types interface


    【解决方案1】:

    这并不像看起来那么神奇。

    您自己在接口IPersonArray 中添加该字段的定义,然后将数组分配给personArray。 TypeScript 知道一个数组有一个length 属性,所以赋值没问题。并在运行时调用数组的长度属性。

    如果您将length 从您的接口/类型中排除,您将无法访问它,就像您无法访问您碰巧分配给personArray 的数组的任何其他属性一样。

    【讨论】:

    • 谢谢!不过,我没有足够的代表来支持你,对不起:(
    【解决方案2】:

    在打字稿中,接口只是编译时使用的契约。

    如果你要编译一个只包含接口的文件,你会得到一个空的(或几乎是空的)文件。

    您的代码正在做的是:定义一个名为IPersonArray 的接口,这意味着 - 每个实现这个接口的类至少应该实现length[]。 - 如果将此接口用作 var 类型,则您的 var 只能访问 length[],并且分配给此 var 的值应该具有兼容的类型(any 除外)。

    JS 的原生数组(Typescript 可识别)具有 length[],因此您可以将其分配给 IPersonArray 类型的 var。

    但是...您也可以有一个通过编译但在运行时完全错误的代码:

    let anyType: any = { notLenght: ":scream:" };
    let typedArray: IPersonArray = anyType;
    
    let count: number = typedArray.length; // `undefined`, since there is `length` in `anyType`
    

    顺便说一句:

    一个。你可以对数组使用泛型:Array&lt;Person&gt; 相当于你的接口IPersonArray

    b.您可以使用for of 来迭代 Typescript 中的数组(取决于您使用的版本)

    for (let person of personArray) {
      console.log(person.fullName);
    }
    

    【讨论】:

    • 我刚开始学习 TypeScript,还没有接触到泛型。感谢您花时间写出如此深入的答案,它确实为我清除了很多东西!
    猜你喜欢
    • 1970-01-01
    • 2019-05-30
    • 2017-11-08
    • 2017-10-20
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2019-11-16
    相关资源
    最近更新 更多