是否可以在 TypeScript 类型和泛型键类型中混合使用特定的类型化键?



我正在尝试创建一个类型来描述 ES6 Proxy 对象,在该对象中,我将知道几个键的类型,其余键将是通用的,回调作为值,直到运行时我才知道它们的名称。

但是,如果我尝试这样的事情:

interface MyCallback {
(): void;
}
interface MyType {
myKey1: number;
[key: string]: MyCallBack;
}

我收到以下错误:

[ts] Property 'myKey1' of type 'number' is not assignable to string index type 'MyCallback'.

如果我添加[key: string]: number,我会得到错误Duplicate string index signature

如果我重载它,就像number | MyCallback一样,如果我尝试在MyType实例上调用回调,我会收到此错误:

[ts] Cannot invoke an expression whose type lacks a call signature. Type 'number | MyCallback' has no compatible call signatures.

是否可以拥有我尝试在 TypeScript 中创建的类型?

答案是有点。您可以使用交集类型来实现此目的:

interface MyType {
myKey1: number;
}
interface MyCallBack {
(): void;
}
interface GenericCallbackType {
[key: string]: MyCallBack;
}
type CombinedType = MyType & GenericCallbackType;
const obj: CombinedType = {
myKey1: 8,
anyString: () => {}
}

如评论中所述,接受的答案不适用于作业,导致Property 'myKey1' is incompatible with index signature错误。要处理作业,我们可以在这里利用@jcalz的答案:

interface MyCallback {
(): void
}
interface MyType {
myKey1: number
}
const asCombinedType = <C>(
res: C & MyType & Record<Exclude<keyof C, keyof MyType>, MyCallback>
): C => res
const obj = asCombinedType({
anyKey: () => { /* ...*/ },
myKey1: 12
})

诚然有点复杂,但它可以完成工作。

接受的答案对我不起作用,这个片段有效: 游乐场链接

interface MyType {
myKey1: number;
}
interface GenericCallbackType {
[key: string]: () => void;
}
type CombinedType = MyType | GenericCallbackType;
const obj: CombinedType = {
myKey1: 8,
anyString: () => {}
}

最新更新