【问题标题】:Is it possible to infer a generic class type from a non-constructor method parameter in Typescript?是否可以从 Typescript 中的非构造方法参数推断出泛型类类型?
【发布时间】:2018-11-17 23:06:10
【问题描述】:

A-构造方法案例

当我想从构造方法参数推断泛型类类型时:

interface ObjectAsMap { [key: string]: boolean }

interface MyClass<T extends ObjectAsMap> {
  data: T

  constructor(data: T): MyClass<T>
}

class MyClass<T extends ObjectAsMap> {
  constructor(data: T) {
    this.data = data
  }
}

const a = new MyClass('Wrong parameter type')
const b = new MyClass({
  first: true,
  second: false,
})

console.log(b.data.first)
console.log(b.data.wrongProperty)

不出所料,我得到了2 errors

  • new MyClass('Wrong parameter type') 触发 Argument of type '"Wrong parameter type"' is not assignable to parameter of type 'ObjectAsMap'.
  • b.data.wrongProperty 触发 Property 'wrongProperty' does not exist on type '{ first: true; second: false; }'.

B- 非构造方法案例

现在,如果我想从非构造方法触发完全相同的预期行为:

interface ObjectAsMap { [key: string]: boolean }

interface MyClass<T extends ObjectAsMap> {
  data: T

  declare(data: T): MyClass<T>
}

class MyClass<T extends ObjectAsMap> {
  public data: T

  public declare(data: T) {
    this.data = data

    return this
  }
}

const myClassInstance = new MyClass()

const a = myClassInstance.declare('Wrong parameter type')
const b = myClassInstance.declare({
  first: true,
  second: false,
})

console.log(b.data.first)
console.log(b.data.wrongProperty)

我只得到the first error:

  • myClassInstance.declare('Wrong parameter type') 触发 Argument of type '"Wrong parameter type"' is not assignable to parameter of type 'ObjectAsMap'.

b.data.wrongProperty 也应该触发错误,因为b#data 中不存在此属性。当我将鼠标悬停在b.data 上方时,它告诉我(property) MyClass&lt;ObjectAsMap&gt;.data: ObjectAsMap 而不是(property) MyClass&lt;{ first: true; second: false; }&gt;.data: { first: true; second: false; }


问题

有没有办法像我在案例 A 中那样推断案例 B 中的参数类型?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你只需要添加一个额外的类型参数来捕获调用中data的实际类型

    interface ObjectAsMap { [key: string]: boolean }
    
    interface MyClass<T extends ObjectAsMap> {
        data: T
    
        declar<U extends T>(data: U): MyClass<U>
    }
    
    class MyClass<T extends ObjectAsMap> {
        public data: T
    
        public declare<U extends T>(data: U): MyClass<U> {
            this.data = data
    
            return this as any
        }
    }
    
    const myClassInstance = new MyClass()
    
    const a = myClassInstance.declare('Wrong parameter type')
    const b = myClassInstance.declare({
        first: true,
        second: false,
    })
    
    console.log(b.data.first)
    console.log(b.data.wrongProperty)
    

    【讨论】:

    • 它仍然没有捕捉到我刚刚测试的参数类型。您可以仔细检查playground(代码共享链接太长,无法在评论中插入)
    • @EdouardHienrichs 不是你的意思.. 我在b.data.wrongProperty 上收到错误消息。不会影响原myClassInstance的类型
    • 对不起@titian-cernicova-dragomir 我确实忘记了第二个返回声明为MyClass&lt;U&gt;。成功了,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-03-11
    • 2016-12-05
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多