TypeScript接口,允许其他属性

时间:2015-11-20 21:53:08

标签: typescript

总之,是否可以使用一个声明某些基本属性的接口,但不限制其他属性?这是我目前的情况:

我正在使用Flux pattern,它定义了一个通用调度程序:

class Dispatcher<TPayload> {
    dispatch(arg:TPayload):void { }
}

然后我创建一个具有自己的有效负载类型的调度程序,如下所示:

interface ActionPayload {
    actionType: string
}

const dispatcher = new Dispatcher<ActionPayload>();

现在我有一些动作代码可以使用一些额外的数据调度有效负载,但ActionPayload接口只允许actionType。换句话说,这段代码:

interface SomePayload extends ActionPayload {
    someOtherData: any
}

class SomeActions {
    doSomething():void {
        dispatcher.dispatch({
            actionType: "hello",
            someOtherData: {}
        })
    }
}

出现编译错误,因为someOtherDataActionPayload接口不匹配。问题是许多不同的“行动”类会重复使用同一个调度程序,所以虽然它someOtherData在这里可能是anotherKindOfData,依此类推。目前,我所能做的就是使用new Dispatcher<any>(),因为将分派不同的动作。但是,所有操作都共享一个基础ActionPayload,所以我希望能够限制像new Dispatcher<extends ActionPayload>()之类的类型。有可能吗?

4 个答案:

答案 0 :(得分:55)

如果您希望ActionPayload接受任何其他属性,您可以添加索引器:

interface ActionPayload {
    actionType: string,
    [x: string]: any 
}

请参阅https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#strict-object-literal-assignment-checking

答案 1 :(得分:0)

我想我找到了我想要的东西。我可以将调度的对象强制转换为SomePayload,并且TSC验证它与转换接口和调度程序的TPayload兼容:

    dispatcher.dispatch(<SomePayload>{
        actionType: "hello",
        someOtherData: {}
    })

Example online.

答案 2 :(得分:0)

interface Options {
  darkMode?: boolean;
  [otherOptions: string]: unknown;
  }

答案 3 :(得分:0)

如果从对象定义中推断出您的类型,则可以断言该类型为原始类型与{[key: string]: any]}的并集:

const obj = { foo: 42 };
return obj as typeof obj & {[key: string]: any]};

通过这种方式,IntelliSense会建议您foo,但在您尝试使用分配或使用其他密钥时不会抱怨。

无论如何,如果附加键很少,并且它们是先验的,则可以将它们添加为类型定义中的可选键:

const obj: {foo: number; bar?: string} = {foo: 42}