【问题标题】:TS(2352) Declare object with dynamic properties and one property with specific typeTS(2352) 声明具有动态属性和一个具有特定类型的属性的对象
【发布时间】:2019-10-14 10:04:25
【问题描述】:

我需要创建一个对象,该对象将包含一个名为“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)

我了解该问题与尝试将属性 state 转换为 [methodName: string]: (this: ContextModule&lt;State&gt;, ...args: any[]) =&gt; any 的 TypeScript 相关,但是为什么我在声明动态属性之前声明了此属性

可能有人看到了同样的问题。希望得到您的帮助,谢谢!

【问题讨论】:

    标签: typescript typescript-typings typescript2.0


    【解决方案1】:

    我可以让它干净地工作的唯一方法是使用交集类型,但似乎动态类型和具有固定属性的类型(与动态道具的类型不同)的交集只能使用 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 的方法吗?如果是真的那么我会结束我的问题
    • @SergeyVolkov 我不知道,但我从比大多数人更了解 TS 的人那里得到了信息。请参阅此处的 cmets:stackoverflow.com/a/53090809/14357 不过我找不到任何其他参考。
    猜你喜欢
    • 2015-10-21
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多