为什么接口中可选属性的占位符只能是任何类型?

时间:2018-06-21 13:24:37

标签: typescript

我有一个带有单个声明的文件,它是接口:

interface NamedPerson {
    firstName: string;
    age?: number;
    [propName: string]: any;
    greet(lastName: string): void;
}

只要我保留[propName:string]:任何的类型,它就可以正常工作。如果我将其更改为数字或其他可能的错误,则会收到错误消息:

  

[ts]类型'(lastName:string)=> void'的属性'greet'不能分配给字符串索引类型'number'。

我希望使用NamedPerson接口的对象的未指定新属性只能是 number 类型,而不能是其他类型。

问题:界面出了什么问题,我该如何调整它以适应我的需求?

1 个答案:

答案 0 :(得分:2)

它不必是any类型,但它必须是包含 all 其他字段类型的类型。在您的情况下,这将是string(由于firstName),number(由于age)和(p: string) => void(由于greet

interface NamedPerson {
    firstName: string;
    age?: number;
    [propName: string]: string | number | ((p: string)=> void);
    greet(lastName: string): void;
}

Typescript强制索引返回类型和已知字段之间的一致性(因为索引可用于返回任何已知字段)。如果使用相交类型,则可以创建不一致的索引:

type NamedPerson = {
    firstName: string;
    age?: number;
    greet(lastName: string): void;
} & {
    [propName: string]: number;
};

问题是您将无法直接创建此类对象,只能使用Object.assign和一些类型断言来创建它:

let n: NamedPerson = Object.assign({
    firstName: "",
    age: 0,
    greet(lastName: string): void { }
}, {} as { [propName: string]: number });