使用动态属性声明对象并具有一个特定类型的属性

4

我需要创建一个对象,其中将包含一个名为“state”的属性,该属性将具有通用类型,并且所有其他属性都将是具有覆盖上下文的函数。 我不确定是否可能,因此我决定在这里写下来。

以下是我的代码:

declare interface ContextModule<State> {
  state: State
}

export declare interface SuperModule<State = any> {
  state?: State | any,
  [methodName: string]: (this: ContextModule<State>, ...args: any[]) => any
}

const lol = {
  getFoo (): any {
    return this.state.foo
  }
} as SuperModule

在这段代码中,我没有任何错误。它可以成功执行,但是如果我添加
declare interface ContextModule<State> {
  state: State
}

export declare interface SuperModule<State = any> {
  state?: State | any,
  [methodName: string]: (this: ContextModule<State>, ...args: any[]) => any
}

const lol = {
  getFoo (): any {
    return this.state.foo
  },
+  state: {       // added this property
+    foo: 'string'
+  }
} as SuperModule

然后我将会看到输出。
Conversion of type '{ getFoo(this: ContextModule<any>): any; state: { foo: string; }; }' to type 'SuperModule<any>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Property 'state' is incompatible with index signature.
    Type '{ foo: string; }' is not comparable to type '(this: ContextModule<any>, ...args: any[]) => any'.
      Type '{ foo: string; }' provides no match for the signature '(this: ContextModule<any>, ...args: any[]): any'.ts(2352)

我理解这个问题与TypeScript试图将属性state转换为[methodName: string]: (this: ContextModule<State>, ...args: any[]) => any有关,但是为什么如果我在动态属性声明之前声明了这个属性呢?
也许有人遇到过相同的问题。希望你能帮忙解决,谢谢!
1个回答

4

我想要这个功能干净的工作方式是使用交叉类型,但看起来只有使用 Object.assign 才能创建具有不同类型的固定属性(与动态属性)的类型之间的交叉。

下面是一个简化示例:

interface MyType {
    requiredProp1: string
}
interface MyOtherType{
    [key: string]: number
}
type ISect = MyType & MyOtherType

const obj: ISect = Object.assign({ requiredProp1: "ff" }, { foo: 1 })

const rp1 = obj.requiredProp1 //string
const foo = obj.foo //number

谢谢你的回答! 这是 TypeScript 中唯一可行的方法吗?如果是,那我就会关闭我的问题。 - Sergey Volkov
1
@SergeyVolkov 我不确定,但我是从一个比大多数人更了解TS的人那里得到的信息。看看这里的评论:https://dev59.com/fq_la4cB1Zd3GeqPt4Bs#53090809 不过我没找到其他相关的参考资料。 - spender

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接