我有一个奇怪的问题,当我尝试使用带参数的函数调用该函数时,会遇到打字稿错误。
我想达到的目标是拥有任何一种基本类型。可以将这种基本类型转换为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!
}