[英]TypeScript - How do you infer a class generic type from a method's parameter?
[英]Is it possible to infer a generic class type from a non-constructor method parameter in Typescript?
當我想從構造函數方法參數推斷通用類類型時:
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個錯誤 :
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; }'.
Property 'wrongProperty' does not exist on type '{ first: true; second: false; }'.
現在,如果我想從非構造方法中觸發完全相同的預期行為:
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)
我只得到第一個錯誤 :
myClassInstance.declare('Wrong parameter type')
觸發器Argument of type '"Wrong parameter type"' is not assignable to parameter of type 'ObjectAsMap'.
。 由於b#data
中不存在此屬性,因此b.data.wrongProperty
也應觸發錯誤。 當我將鼠標懸停在b.data
上方b.data
,它告訴我(property) MyClass<ObjectAsMap>.data: ObjectAsMap
而不是(property) MyClass<{ first: true; second: false; }>.data: { first: true; second: false; }
(property) MyClass<{ first: true; second: false; }>.data: { first: true; second: false; }
(property) MyClass<{ first: true; second: false; }>.data: { first: true; second: false; }
。
有沒有辦法像情況A那樣推斷情況B中的參數類型?
您只需要添加一個額外的type參數即可捕獲調用中的實際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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.