简体   繁体   English

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

[英]Is it possible to define a function within an indexable type interface in typescript?

I'd like to define the following: 我想定义以下内容:

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

This way I can get an object that adheres to the IValidationContextIndex interface and call getValidationContexts on it. 这样,我可以得到一个坚持IValidationContextIndex接口的对象,并对其调用getValidationContexts

However VSCode is NOT HAPPY with this type of definition. 但是,VSCode对这种类型的定义不满意。 Is it possible to do this in an interface or do I need something like: 是否可以在界面中执行此操作,或者我是否需要以下内容:

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

The problem is that typescripts would prefer that the index signature be consistent will ALL declared members. 问题在于打字稿希望索引签名与所有声明的成员保持一致。 Since you can use the index to access the getValidationContexts member as well and it's type will not be ValidationContext . 由于您还可以使用索引来访问getValidationContexts成员,因此其类型将不是ValidationContext

You can make the index signature consistent will the defined members, but it's not ideal as you will need to narrow the return type: 您可以使索引签名与定义的成员保持一致,但这并不理想,因为您需要缩小返回类型:

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

A way to get around this restriction is to use an intersection type: 克服此限制的一种方法是使用交叉点类型:

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

But objects of this type can't be created directly, for the same index incompatibility reason. 但是由于相同的索引不兼容原因,无法直接创建此类型的对象。 You would need to create the objects using Object.assign : 您将需要使用Object.assign创建对象:

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

Or using a type assertion: 或使用类型断言:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM