【问题标题】:Is it possible to create a typescript type from an array?是否可以从数组创建打字稿类型?
【发布时间】:2019-07-27 22:43:12
【问题描述】:

我经常使用诸如

之类的代码
export type Stuff = 'something' | 'else'
export const AVAILABLE_STUFF: Stuff[] = ['something', 'else']

这样我既可以使用类型Stuff,也可以在需要时遍历所有可用的东西。

这行得通,但感觉就像重复了两次信息。而且您必须小心,因为更新 StuffAVAILABLE_STUFF 也需要更新其对应项。

有没有更好的方法来定义数组的类型,或者甚至在某种程度上使用数组来输入一些数据?

【问题讨论】:

  • 你想用类型填充数组还是这样使用数组的用例到底是什么?
  • @MuratKaragöz 有点像。我希望只需一份声明就能从const x: StuffAVAILABLE_STUFF.forEach(stuff => ...) 的好处中获益。我不在乎我是否必须声明一个数组、一个类型或其他我还不知道的东西:)
  • 你考虑过使用字符串enum吗?看起来它应该做你想做的事。它是一种类型,您可以迭代值。

标签: typescript typescript-typings


【解决方案1】:

一个内置选项是使用枚举而不是类型和数组方法。

export enum Stuff {
    something = 'something',
    else = 'else',
}

export const AVAILABLE_STUFF: Stuff[] = Object.values(Stuff);

另一种选择是从AVAILABLE_STUFF 的类型中提取类型。为此,我们必须强制编译器推断AVAILABLE_STUFF 的字符串文字元组。这可以在3.4as const 中完成,或者在3.4 之前使用一个额外的函数来完成。在AVAILABLE_STUFF 是元组类型之后,我们可以使用类型查询来获取元素的类型:

export const AVAILABLE_STUFF = (<T extends string[]>(...o: T)=> o)('something', 'else'); // typed as ["something", "else"]
// export const AVAILABLE_STUFF = ['something', 'else'] as const; // typed as ["something", "else"]  in 3.4
export type Stuff = typeof AVAILABLE_STUFF[number] //"something" | "else"

上面代码的一些解释。 typeof AVAILABLE_STUFF 为我们提供了常量的类型 (["something", "else"]) 以获取 [number] 称为 type query 并将为我们提供元组中项目的类型。

(&lt;T extends string[]&gt;(...o: T)=&gt; o) 只是我们用来强制编译器推断字符串文字元组类型的 IIFE。它必须是通用的,因为编译器只会在某些情况下推断文字类型和元组(具有string 约束的类型参数就是其中之一)。 as const 版本是我建议在它可用时使用的版本,因为它更具可读性。

【讨论】:

  • 在第二个解决方案中,我看到Stuff 类型被正确推断,但我不明白语法。 [number]typeof AVAILABLE_STUFF[number]中的作用是什么?
  • @Paleo 添加了一些解释,让我知道现在是否更清楚了。
  • 我明白了!谢谢。
  • @aherve 它不是一个完美的替代品。您需要在 TS 代码中使用 let a: Stuff = Stuff.something。在运行时a 的值将是something
  • @MoshFeu 这应该可以:typescriptlang.org/play/…
【解决方案2】:

Typescript v3.4 相当简单

你可以这样做-

export const AVAILABLE_STUFF = <const> ['something', 'else'];
export type Stuff = typeof AVAILABLE_STUFF[number];

更多信息 - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions

【讨论】:

  • 为什么必须是AVAILABLE_STUFF[number] 而不仅仅是AVAILABLE_STUFF[]
  • 因为数组中的“键”是数字。
【解决方案3】:

另一种可能性是创建一个对象并使用keyof。仅当您有任何有用的值可存储为值时,我才建议使用这种方式(以替换下面代码中的 null)。

const stuffDict = {
  something: null,
  else: null,
}

type Stuff = keyof typeof stuffDict
const AVAILABLE_STUFF = Object.keys(stuffDict) as Stuff[]

【讨论】:

  • 也是一个不错的解决方案
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2021-02-02
  • 2017-12-27
  • 2020-02-10
  • 2012-12-14
  • 1970-01-01
  • 2016-10-19
  • 2020-10-05
相关资源
最近更新 更多