我有一个带有单个声明的文件,它是接口:
interface NamedPerson {
firstName: string;
age?: number;
[propName: string]: any;
greet(lastName: string): void;
}
只要我保留[propName:string]:任何的类型,它就可以正常工作。如果我将其更改为数字或其他可能的错误,则会收到错误消息:
[ts]类型'(lastName:string)=> void'的属性'greet'不能分配给字符串索引类型'number'。
我希望使用NamedPerson接口的对象的未指定新属性只能是 number 类型,而不能是其他类型。
问题:界面出了什么问题,我该如何调整它以适应我的需求?
答案 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 });