我想定义一个函数,以便该函数使作为参数传递的对象的this个属性可用.例如,以下是某人调用函数的方式:

const props = ['bar'];
myBarFunction(props, {
    get foo() {
        return fooify(this.bar)
    }
});

Here, I would want the bar property to be available in this (normally typescript would throw an error complaining there is no bar in this).
Something similar seems possible in Vue's defineComponent. Though, I'm unsure how or if that could be implemented in TypeScript or if it's something provided by Vue's Volar extension.
Is there a way for a function like myBarFunction to be declared?

推荐答案

你需要用the magic ThisType<T> utility type美元.值为ThisType<T>类型的object literal将其方法的this变量contextually typed作为T.ThisType是"神奇的",因为您无法自己定义这样的实用程序类型:它的definition in the lib files只是一个空接口{};编译器将其特例用于必要的上下文类型.

好的,所以myBarFunction可以有这样的呼叫签名:

declare function myBarFunction<K extends string>(
  props: readonly K[],
  obj: ThisType<{ [P in K]: string }>
): void;

这里的函数是K中的generic,这是props数组的类键元素类型.objThisType{ [P in K]: string },相当于用Record<K, V> utility type乘以Record<K, string>.因此,为obj传入的对象文本的每个方法都将有一个this上下文,该上下文具有string值的属性,其键在props数组中.

让我们来测试一下:

const props = ['bar'] as const; // <-- note, const assertion

myBarFunction(props, {
  get foo() {
    return fooify(this.bar.toUpperCase()) // okay
  }
});

请注意,在声明props时需要const assertion或类似的值,否则const props = ["bar"]会导致props被推断为string[],这将完全失go "bar" literal type的轨迹.

而且它起作用了!如果您将鼠标悬停在this上方,您会看到它的类型是{bar: string}.

Playground link to code

Typescript相关问答推荐

Typescript对每个属性具有约束的通用类型

如何推断类方法未知返回类型并在属性中使用它

如果在TypeScript中一个原始的类方法是递归的,如何使用类decorator 模式?

类型脚本类型字段组合

如何使函数接受类型脚本中具有正确类型的链接修饰符数组

使用2个泛型类型参数透明地处理函数中的联合类型

如何创建一家Reduxstore ?

TypeError:正文不可用-NextJS服务器操作POST

TypeScrip泛型类未提供预期的类型错误

将具有Readonly数组属性的对象接口转换为数组

如何从MAT-FORM-FIELD-MAT-SELECT中移除焦点?

刷新时保持当前名称的Angular

如何按属性或数字数组汇总对象数组

Typescript -返回接口中函数的类型

对有效枚举值的常量字符串进行常规判断

如何在Reaction 18、Reaction-Rout6中的导航栏中获取路由参数

为什么`map()`返回类型不能维护与输入相同数量的值?

替换typescript错误;X类型的表达式可以';t用于索引类型Y;带有未定义

如何按成员资格排除或 Select 元组?

Typescript,如何从对象的对象中获取分离的类型