关于typescript:TS(2352)声明具有动态属性的对象和具有特定类型的一个属性

TS(2352) Declare object with dynamic properties and one property with specific type

我需要创建一个对象,该对象将包含一个名称为" state"的属性,该属性将具有泛型类型,而所有其他属性将是具有覆盖上下文的函数。我不确定是否有可能,因此我决定在这里写。

我有一个代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

在此代码中,我没有任何错误。它执行成功,但是如果我要添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

然后我将看到输出

1
2
3
4
Conversion of type '{ getFoo(this: ContextModule): any; state: { foo: string; }; }' to type 'SuperModule' 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, ...args: any[]) => any'.
      Type '{ foo: string; }' provides no match for the signature '(this: ContextModule, ...args: any[]): any'.ts(2352)

我了解与该TypeScript关联的问题,试图将属性state强制转换为[methodName: string]: (this: ContextModule<State>, ...args: any[]) => any,但是为什么我在声明动态属性之前声明了此属性

也许有人看到了同样的问题。希望对您有所帮助,谢谢!


我可以使它正常工作的唯一方法是使用交集类型,但是似乎只能使用Object.assign创建动态类型和具有固定属性的类型(与动态道具的类型不同)的交集。

这是我如何简化工作的简化示例:

1
2
3
4
5
6
7
8
9
10
11
12
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