如何从 Typescript 中的类元组中提取鉴别器

Posted

技术标签:

【中文标题】如何从 Typescript 中的类元组中提取鉴别器【英文标题】:How to extract discriminator from tuple of classes in Typescript 【发布时间】:2021-07-27 11:18:27 【问题描述】:

给定以下代码:

abstract class Fruit 
  abstract readonly fruitType: string;


class Banana extends Fruit 
  readonly fruitType = "banana";
  length = 2;
  color = "yellow";


class Pear extends Fruit 
  readonly fruitType = "pear";
  roundness = "very round";


class Apple extends Fruit 
  readonly fruitType = "apple";
  fallOfMan = true;
  hasWorms = true;


const fruits = [Banana, Pear, Apple] as const;


export type Fruits = typeof fruits[number];


export type FruitTypes = Fruits["fruitType"]; // This should be "banana" | "pear" | "apple"

为什么我无法得到正确的鉴别器联合?

这里是操场:https://www.typescriptlang.org/play?#code/IYIwzgLgTsDGEAJYBthjAgYlArgS0QG8BYAKAQVEhngSgFNgATAewDtkBPBAM1wIAqnAA70AXAmp42AcwDcZAL5kyKNBgBCwNtuAJ6ADwj02TDNnxEyFBs3Zde-CENEIAvAgBEIXTs8LyBGQTGQgAC3cEACYAilgWZBYoSM9OemREgHd-JRVSNXQEAAVGZMNjU3MnBBJA21YObj5LF3oU0WAoHLqWHFM2ekKPTwA3eihuKF7TbuVSVVRCgEFhYWD9IxMzLGram0YGh2bBETbh4FXg7ooeYAyAeR4AWW1I6Bx6WIQwtAB1JIAthgPO9Prl5vl2JBHJZgQgANpaHQ6AA0xVKaJWa3oAF1KBh4mxIAE8oZhElEBBTjtYW9TiweDCCGB4WwcACQOMcSSIWSKQgqa4LCdRHDhRAWZ5js5Tp5uQgAPQKhACMJ4DBgMK9ZBMBCcrw+ZHATwIAA+Xg6XTNXgu2M8QA

【问题讨论】:

你的意思是Fruits["fruitType"] 吗? @BenWainwright - 这给出了一个错误:tsplay.dev/Wyv7bw。 Fruitstypeof Banana | typeof Pear | typeof Apple(构造函数类型),而不是 Banana | Pear | Apple 我并不是说它是解决方案,但我没有将“名称”视为您代码中任何地方的属性... @BenWainwright - 它们是构造函数。函数有一个name 属性。 (我不是 OP。:-)) @mikeysee - fruitsFruits 的类型真的是你想要的吗?构造函数(及其类型)? 【参考方案1】:

我回答时你的问题是:

// Original code in question
export type FruitTypes = Fruits["name"];

Fruits 是构造函数 BananaPearApple 的类型的联合——实际的函数,而不是它们产生的实例的类型。 (构造函数)函数的name 始终是一个字符串,这就是你最初得到string 的原因。更新后的问题现在出现错误,因为这些构造函数没有 fruitType 成员。

您可以使用InstanceType 获取您想要的联合,以获取这些构造函数创建的实例的类型,并使用"fruitType" 访问这些实例的fruitType 成员的类型:

export type FruitTypes = InstanceType<Fruits>["fruitType"];
// −−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^−−−−−−^^^^^^^^^^^^^^

Playground Link

或者你可以更直接:

export type FruitTypes = (Banana | Pear | Apple)["fruitType"];

...但我猜您出于维护原因试图避免重复该列表(在上面以及fruits)。

【讨论】:

太棒了! InstanceType 是我要找的帮手,谢谢! :)

以上是关于如何从 Typescript 中的类元组中提取鉴别器的主要内容,如果未能解决你的问题,请参考以下文章

如果键匹配,如何从元组中提取一个值

从Haskell中的元组中提取第n个元素(其中n和元组被赋予参数)

从元组中提取向量

Python求解,,怎样求出元组中的各元素之和?

TypeScript 按任意类型过滤元组类型

从Python中的类元信息类型提示__init__函数