总之,是否可以使用一个声明某些基本属性的接口,但不限制其他属性?这是我目前的情况:
我正在使用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: {}
})
}
}
出现编译错误,因为someOtherData
与ActionPayload
接口不匹配。问题是许多不同的“行动”类会重复使用同一个调度程序,所以虽然它someOtherData
在这里可能是anotherKindOfData
,依此类推。目前,我所能做的就是使用new Dispatcher<any>()
,因为将分派不同的动作。但是,所有操作都共享一个基础ActionPayload
,所以我希望能够限制像new Dispatcher<extends ActionPayload>()
之类的类型。有可能吗?
答案 0 :(得分:55)
如果您希望ActionPayload接受任何其他属性,您可以添加索引器:
interface ActionPayload {
actionType: string,
[x: string]: any
}
答案 1 :(得分:0)
我想我找到了我想要的东西。我可以将调度的对象强制转换为SomePayload
,并且TSC验证它与转换接口和调度程序的TPayload
兼容:
dispatcher.dispatch(<SomePayload>{
actionType: "hello",
someOtherData: {}
})
答案 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}