网站搜索

多态 - 基于配置的 TypeScript 导出类


好的,首先 TypeScript 对我来说相当新,我是一个长期的 C# 开发者,但很喜欢我能在 Node/TypeScript 中快速搞定的东西——我有一个语法问题(我想是语法问题),我有一个接口被两个具体类实现,还有第三个模块根据配置导出其中一个具体类,即

fruit.ts

export interface Fruit {
  eat();
}

apple.ts

export class Apple implements Fruit {
  eat() { console.log('Eat apple'); }
}

banana.ts

export class Banana implements Fruit {
  eat() { console.log('Eat banana'); }
}

早餐.ts

import { Fruit } from 'fruit';
import { Apple } from 'apple';
import { Banana } from 'banana;

const BreakfastType: typeof Fruit = config.appleForBreakfast ? Apple : Banana;   <-- Error

export { BreakfastType }

这看起来应该对我有用,苹果和香蕉是“水果类型”,所以将 BreakfastType 声明为“Fruit 的类型”我认为是有道理的,但 TypeScript 却报错

水果只指一种类型,但这里被用作一个值

这显然是一个人为的例子,但完全符合我想做的,我希望其他代码也能这样

import { BreakfastType } from 'breakfast';
let breakfastFood = new BreakfastType();    <-- create Apple or Banana based on config

非常感谢任何建议

答案#1

所以,这里有几个问题,第一个问题是你 不能 对 TypeScript 类型使用 typeof,但你 可以 仅对 JS 变量、类、对象以及所有其他非 TypeScript 的东西使用它。因此,下一行不应该有 typeof Fruit:

const BreakfastType: typeof Fruit = config.appleForBreakfast ? Apple : Banana;

相反,它需要像那样:

const BreakfastType: Fruit = config.appleForBreakfast ? Apple : Banana;

但是又出现了另一个问题,它仍然抱怨类型:Property 'eat' is missing in type 'typeof Apple' but required in type 'Fruit'。经过一些研究后,我发现如果你以上面的方式指定BreakfastType,TypeScript 会这样看它:

它将 BreakfastType 视为 Fruit 类型的变量,但我们尝试给它赋值 Apple 或 Banana。但是它们是 类,而不是这些类的 实例。因此,作为解决方案,你可以明确指出 BreakfastType 是一个类,而不是通过 new() => Fruit 的实例。

const BreakfastType: (new () => Fruit) = config.appleForBreakfast ? Apple : Banana
const MyBreakfast = new BreakfastType() // MyBreakfast will have Fruit type now