首页 > 解决方案 > 我应该将哪种类型用于打字稿中的实例属性?

问题描述

我有 class 的实例Foo

我想从变量中打印hi属性,例如:string

class Foo {
    hi() { console.log('hi') }
}

const instance = new Foo();

const go = (field: string): void => instance[field]()

go('hi')

https://www.typescriptlang.org/play?ssl=9&ssc=9&pln=1&pc=1#code/MYGwhgzhAEBiD29oG8CwAoAkACwJYAoBKFaYeAOwnhAFMA6EeAc3wHI9XiBfDH9DMpQAu0XMLDlgNaAF5o5GgHc4iIgG4MAihBFMkc-ADNcNEABMAXNB0AnMU0JWAbvFxnZAPlHjJNANrGpmYAukSa6HpsHIRAA

哪种类型必须是property可变的?它不是打字稿的字符串。

错误:

类型,因为“字符串”类型的表达式不能用于索引类型 Foo

标签: typescripttypes

解决方案


首先,我们应该确保属性名称是可调用的。想象一下情况,您有一个具有混合属性的实例。可调用而不可调用。

class Foo {
    notCallable = 10
    hi() { console.log('hi') }
}

const instance = new Foo();


type Fn = (...args: any[]) => any

type Callable<T> = {
    [Prop in keyof T]: T[Prop] extends Fn ? Prop : never
}[keyof T]

type Test = Callable<typeof instance> // 'hi'

您可能已经注意到,Callable仅返回可调用属性。

让我们将我们的限制应用于函数:

class Foo {
    notCallable = 10
    hi() { console.log('hi') }
}

const instance = new Foo();


type Fn = (...args: any[]) => any

type Callable<T> = {
    [Prop in keyof T]: T[Prop] extends Fn ? Prop : never
}[keyof T]

type Test = Callable<typeof instance> // 'hi'


const call = <Obj,>(inst: Obj) =>
    <Key extends Callable<Obj>>(key: Key) =>
        inst[key]();

const applyObject = call(instance);

const callMethod = applyObject('hi')

尝试提供除hito之外的任何其他属性applyObject,TS 会抛出错误

操场


推荐阅读