首页 > 解决方案 > 是否可以从数组创建打字稿类型?

问题描述

我经常使用诸如

export type Stuff = 'something' | 'else'
export const AVAILABLE_STUFF: Stuff[] = ['something', 'else']

这样我既可以使用 type Stuff,也可以根据需要遍历所有可用的东西。

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

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

标签: typescripttypescript-typings

解决方案


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

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

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

另一种选择是从AVAILABLE_STUFF. 为此,我们必须强制编译器推断AVAILABLE_STUFF. 这可以在使用额外功能的3.4同时as const或之前完成。3.4AfterAVAILABLE_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]称为类型查询,并将为我们提供元组中项目的类型。

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


推荐阅读