繁体   English   中英

使用字符串定义类型与 object 文字属性

[英]Define Type with strings versus object literal properties

我已经倾注了 TS 文档,但似乎无法找到为什么以下内容是非法的答案。

我可以用字符串定义联合类型,但是如果我使用 object 属性的引用创建相同的联合类型,最终引用相同的字符串值,编译器就会不高兴。

通过 typescript 操场进行演示

// Success
export type SortOrderWithStrings = 'asc' | 'desc';

export const SortOrderStatic = {
  ASC: 'asc',
  DESC: 'desc',
}

// Fail
export type SortOrderWithObject = SortOrderStatic.ASC | SortOrderStatic.DESC;

错误如下。 为什么这是一个命名空间问题?

Cannot find namespace 'SortOrderStatic'
Exported type alias 'SortOrderReference' has or is using private name 'SortOrderType'

最终,最好有一个Column接口来定义支持的排序顺序类型,然后用SortOrderStatic实例化一个Column以避免魔术字符串,但根据上述情况,这似乎是不可能的。

interface Column {
  label: string;
  defaultSortOrder: SortOrderWithObject;
}

const MyColumn: Column = {
  label: 'My Column',
  defaultSortOrder: SortOrderStatic.ASC
}

如果我按如下方式定义接口(使用SortOrderWithStrings ),然后尝试使用SortOrderStatic ,编译器再次不高兴。

interface Column {
  label: string;
  defaultSortOrder: SortOrderWithStrings;
}

const MyColumn: Column = {
  label: 'My Column',
  defaultSortOrder: SortOrderStatic.ASC
}

失败:

Type 'string' is not assignable to type 'SortOrderWithStrings'.

很明显,我在这里遗漏了一些基本的东西,我很感激任何见解。

很明显我在这里遗漏了一些基本的东西

是的,您将编译时与运行时混淆了:除非编译时类型是文字字符串,否则编译器无法保证 object 属性的运行时访问是您认为的字符串。 您的 object 属性是string类型,这意味着在运行时它可以是任何字符串。

字符串文字是不可变的(因此可以静态验证),object 属性访问量不大。

在您的特定情况下,我将只使用enum

enum SortOrder {
  ASC = 'ASC',
  DESC = 'DESC',
}

export { SortOrder }

import { SortOrder } from 'something';
SortOrder.ASC; // ASC as a string

这将保持类型安全,您不能将任何 ol' 字符串传递给需要SortOrder的东西:( Playground

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM