我想通過呼叫來訪問物件中的方法屬性,this.getMethod如下所示:
function defineObj(params) {
// `enhanced` will add `getMethod` to params.__prop__
return enhanced(params)
}
let obj = defineObj({
methods: {
foo: (num) => num,
bar() {
this.getMethod('foo', 1) // will call as `this.methods.foo(1)`
}
}
})
現在,我計劃將這些代碼移動到 Typescript 并獲得型別提示。
當我打電話時this.getMethod('foo', '1'),我希望 IDE 告訴我,我應該使用number而不是string. 而我只是想知道如何使用 Typescript 的 Type 來完成它。
我寫了代碼來做到這一點,但失敗了。
我試圖通過 use 來定義這個方法的背景關系CtrlContext。所以我可以this.getMethod在methods.foo.
type CtrlContext<M> = {
getMethod: <T extends keyof M>(name: T, ...params: M[T] extends (...arg: infer S2) => infer S1 ? S2 : any[] ) => any
}
type Methods<M> = {
[K in keyof M]: (this: CtrlContext<M>, ...params: any) => ReturnType<any>
}
type Ctrls<M> = {
methods: Methods<M>
}
function defineObj<M>(params: Ctrls<M>) {
return params
}
defineObj({
methods: {
foo: (num: number) => num,
foo2: (num1: number, str: string) => num,
bar() {
this.getMethod("foo", ) // Now, the second param is any, not number.
}
}
})
export default {}

在線代碼
現在,我可以得到第一個引數的型別提示,但在輸入第一個引數后無法得到函式引數提示。有什么辦法可以解決嗎?
uj5u.com熱心網友回復:
我沒有getMethod()在您的代碼中看到方法的定義。對于型別引數。您可以簡單地在方法宣告本身中定義它們。
getMethod(name: string, value: number) {
}
然后,如果您在呼叫時將第二個引數分配為字串。打字稿會給出錯誤。
this.getMethod('foo', '1') ?
this.getMethod('foo', 1) ?
uj5u.com熱心網友回復:
我不確定 TypeScript 是否有能力做你想做的事。其他人可能有更好的主意。
但是,您始終可以包裝這些方法,使其顯示為常規的 TypeScript 函式,這樣它在外部看起來更好,并且還可以包含型別安全。
class Wrapper {
constructor(getMethod) {
this.getMethod = getMethod;
}
foo(n: number) {
this.getMethod("foo", n);
}
// include all other methods here
}
這顯然是一項非常乏味的任務,可能不適合您的用例,但我認為無論如何都值得一提。
您也可以為此創建一個代碼生成工具。
uj5u.com熱心網友回復:
我通過使用ThisType和這個例子解決了。
type AnyFunction = (...args: any) => any
type CtrlContext<M> = {
getMethod:
<T extends keyof M>(name: T, ...params: Parameters<T extends keyof M ? M[T] extends AnyFunction ? M[T] : never : never>) =>
ReturnType<T extends keyof M ? M[T] extends AnyFunction ? M[T] : never : never>
}
type Methods<M> = {
[T in keyof M]: M[T]
}
type Ctrls<M> = {
methods: Methods<M> & ThisType<CtrlContext<M>>
}
function defineObj<M>(params: Ctrls<M>) {
return params
}
defineObj({
methods: {
foo(num: number) {
return num
},
bar() {
const val = this.getMethod("foo", 1)
// ^ (property) getMethod: <"foo">(name: "foo", num: number) => number
}
}
})
在線的
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/503792.html
標籤:javascript 打字稿 前端 打字稿打字
