类型不可分配ts(2345)

时间:2019-05-09 05:30:51

标签: typescript

我有一个奇怪的问题,当我尝试使用带参数的函数调用该函数时,会遇到打字稿错误。

我想达到的目标是拥有任何一种基本类型。可以将这种基本类型转换为QueryType,其中允许每个属性

  • 省略
  • 与该类型完全相同(用于相等性
  • 作为对象,进一步指定了如何找到该属性

然后,我创建一个具有通用类型的类,该类必须使用ID属性扩展其他已知类型。

当我从外面用这种类型调用此类时,一切都很好。

尽管从该类的内部,我无法使其正常运行。 Typescript总是抛出错误ts(2345)类型...的参数不能分配给DeepQuery类型的参数。

在下面的代码中,我提供了一些示例,这些示例说明了我已经尝试过的地方以及失败的地方。

有人知道我可能在哪里吗?

interface IdObject {
  readonly id: number
}

type DeepQuery<T> = T extends Array<any>
  ? DeepQueryArray<T[number]>
  : T extends object
  ? DeepQueryObject<T>
  : DeepScalar<T>

interface QueryObject<T> {
  $lt?: T
  $gt?: T
}

interface DeepQueryArray<T> extends Array<DeepQuery<T>> {}
type DeepQueryObject<T> = { [P in keyof T]?: DeepQuery<T[P]> }
type DeepScalar<T> = T | QueryObject<T>

class TestClass<T extends IdObject> {
  testFunction(query: DeepQuery<T>) {
    console.log(query.id) // <- This gives me no error, so obviously typescript knows that my my query will have an id
    console.log(query.unknown) // <- This gives me an expected error, typescript obviously does not know about any unknown property
  }

  testCreateItem() {
    const id: QueryObject<number> = { $lt: 10, $gt: 1 } // <- This works
    this.testFunction({ id }) // <- error again, this is obviously no DeepQuery<T>

    const obj: DeepQuery<T> = {} // <- This already gives an 2345 error, I would have thought this is perfectly legal, as any DeepQuery could be empty 
    this.testFunction(obj) // <- No error here, so if obj were a DeepQuery, all would be fine 

    const obj2: DeepQuery<IdObject> = {} // <- This already gives an 2345 error, I would have thought this is perfectly legal, as any DeepQuery could be empty 
    this.testFunction(obj2) // <- Here I get an error 

    const obj3: DeepQuery<IdObject> = { id: { $gt: 1, $lt: 10 } }
    this.testFunction(obj3) // <- error again, so IdObject does not extend IdObject

    const obj4 = { id: { $gt: 1, $lt: 10 } }
    this.testFunction(obj4) // <- error again
  }
}

class DummyType implements IdObject {
  id: number
}

function testDummy() {
  const tester = new TestClass<DummyType>()

  const obj = new DummyType()
  return tester.testFunction(obj) // <- No error here, so my DummyType obviously extends IdObject

  const obj2 = { id: 5 }
  return tester.testFunction(obj2) // <- No error here, so my obj also extends IdObject

  const obj3 = { id: { $lt: 10 } }
  return tester.testFunction(obj3) // <- No error here, so my obj still  extends IdObject

  const obj4 = { id: { $equals: 10 } }
  return tester.testFunction(obj4) // <- Just to make sure that wrong types throw an error - they do!
}

0 个答案:

没有答案