你好,我再次讲述我的TS冒险和头痛:)

我正在开发一个框架,其中一些类型是未知的,因为用户可以从抽象方法返回任何内容.

在这种情况下,我想推断用户从initialize方法返回的内容,并在同一类的属性中使用该类型.此initialize方法必须返回从Base扩展的类.

代码如下:

class Base {
  method_1() {}
}

class Child extends Base {
  method_2() {}
}

abstract class AbstractClass {
  prop: C

  abstract initialize(): C extends Base
}

class UserClass1 extends AbstractClass {
  initialize() {
    return new Base()
  }

  someMethod() {
    this.prop.method_1()  // Valid, no TS error
    this.prop.method_2()  // Error, it doesn't exist in Base
  }
}

class UserClass2 extends AbstractClass {
  initialize() {
    return new Child()
  }

  someMethod() {
    this.prop.method_1()  // Valid, no TS error
    this.prop.method_2()  // Valid, no TS error
  }
}

在简历中,我必须从initialize方法(从Base扩展)中推断C类型,并将该类型应用于prop.

知道这是否可以做到吗?

先谢谢你.

推荐答案

您可以使用the polymorphic this type来表示AbstractClass的"当前"子类别的类型.然后我们可以说prop的类型是thisinitialize方法的返回类型:

abstract class AbstractClass {
  prop!: ReturnType<this["initialize"]>
  abstract initialize(): Base
}

请注意,ReturnType<this["initialize"]>使用the ReturnType utility type从函数类型中提取返回类型,并使用indexed access typethis中查找initialize属性的类型.

让我们来测试一下:

class UserClass1 extends AbstractClass {
  initialize() {
    return new Base()
  }

  someMethod() {
    this.prop.method_1()  // Valid, no TS error
    this.prop.method_2()  // Error, it doesn't exist in Base
  }
}

class UserClass2 extends AbstractClass {
  initialize() {
    return new Child()
  }

  someMethod() {
    this.prop.method_1()  // Valid, no TS error
    this.prop.method_2()  // Valid, no TS error
  }
}

看起来不错在每种情况下,prop都被赋予类型ReturnType<this["initialize"]>,对于UserClass1,已知该类型仅可分配给Base,而对于UserClass2,已知该类型可分配给Child.

Playground link to code

Typescript相关问答推荐

错误:note_modules/@types/note/globals.d.ts:72:13 -错误TS 2403:后续变量声明必须具有相同的类型

TypScript ' NoInfer '类型未按预期工作

带有微前端的动态React路由问题

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

ANGLE找不到辅助‘路由出口’的路由路径

如何在另一个参数类型中获取一个参数字段的类型?

使用TypeScrip根据(可选)属性推断结果类型

Material UI / MUI系统:我如何告诉TypeScript主题是由提供程序传递的?

如何在TypeScrip中正确键入元素和事件目标?

如何将所有props传递给React中的组件?

如何消除在Next.js中使用Reaction上下文的延迟?

Angular 17子路由

推断从其他类型派生的类型

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

如何静态键入返回数组1到n的函数

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

带有过滤键的 Typescript 映射类型

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

解析错误:DeprecationError: 'originalKeywordKind' 自 v5.0.0 起已被弃用,无法再使用

错误:仅允许在‘使用服务器’文件中导出异步函数