是否可以在打字稿的可索引类型接口中定义函数?

时间:2018-06-27 22:00:08

标签: javascript typescript

我想定义以下内容:

export interface IValidationContextIndex {
    [validationContextKey: string]: ValidationContext;
    getValidationContexts(): Array<ValidationContext>;
}

这样,我可以获得一个附着在IValidationContextIndex接口上的对象,并在其上调用getValidationContexts

但是,VSCode对于这种类型的定义不满意。是否可以在界面中执行此操作,或者我是否需要类似的内容

class cache {
    constructor(public index: IValidationContextIndex ) {};
    getValidationContexts() {return Object.value(<any> index)}
} 

1 个答案:

答案 0 :(得分:2)

问题在于打字稿希望所有已声明的成员的索引签名都保持一致。由于您也可以使用索引来访问getValidationContexts成员,因此其类型将不是ValidationContext

您可以使索引签名与所定义的成员保持一致,但这并不理想,因为您需要缩小返回类型:

export interface IValidationContextIndex {
    [validationContextKey: string]: ValidationContext | (() => Array<ValidationContext>);
    getValidationContexts(): Array<ValidationContext>;
}

规避此限制的一种方法是使用交叉点类型:

type IValidationContextIndex = {
    [validationContextKey: string]: ValidationContext;
} & {
    getValidationContexts(): Array<ValidationContext>;
}

但是由于相同的索引不兼容的原因,不能直接创建这种类型的对象。您将需要使用Object.assign创建对象:

let o : IValidationContextIndex = Object.assign({ a: new ValidationContext() }, {
    getValidationContexts(): Array<ValidationContext> {
        return Object.values(this)as any
    }
});

或使用类型断言:

let o : IValidationContextIndex = {
    getValidationContexts(): Array<ValidationContext> {
        return Object.values(this)as any
    }
} as IValidationContextIndex;