字符串文本作为数据类型的语义



此摘录来自lib.es2015.symbol.wellknown.d.ts

interface Promise<T> {
readonly [Symbol.toStringTag]: "Promise";
}

readonly 的含义是不言而喻的,[Symbol.toStringTag]大概意味着"名为toString的函数属性"。

让我感到困惑的是使用字符串文字作为类型。我不认为这与

readonly [Symbol.toStringTag]: string = "Promise";

否则他们会这样写。那么字符串文本作为类型的含义是什么,运行时的含义是什么?

首先,一个小的更正:[Symbol.toStringTag]不是一个函数,而是由默认的toString()函数检查的Symbol命名的属性。 这个想法是,满足Promise接口的内容通常会在其字符串描述中包含字符串"Promise"


这个问题的最佳答案可能在 TypeScript 手册中的高级类型:字符串文本类型下。

如果变量的类型是字符串、数字或布尔文本,则意味着变量只能采用该值:

const yes: 'foo' = 'foo'; // okay
const no: 'foo' = 'bar'; // error, 'bar' is not assignable to 'foo'

这有几个用途:

  • 文本的联合可以表示允许值的枚举。 (例如,type ShirtSize = 'S'|'M'|'L'|'XL'type starRating = 1|2|3|4|5(
  • 字符串文本可用于表示属性键。(例如,Record<'foo'|'bar',number>本质上等同于{foo: number; bar: number}(
  • 字符串文字可以用作区分类型的标签:(例如,type Dog = {type: 'dog', bark():void}; type Cat = {type: 'cat', meow():void}; declare let animal: Dog | Cat; if (animal.type === 'dog') animal.bark(); else animal.meow();(
  • 以及更多.. 查看上面列出的文档以获取更多信息

请注意:TypeScript 的类型系统不会发送到 JavaScript 中。 这意味着你往往会发现自己重复文字:一次作为类型,一次作为值:

const foo: 'foo' = 'foo';

第一个'foo'是类型,第二个是值。 如果省略该值,

const foo: 'foo';

那么你在运行时有一个未定义的值,这很糟糕。


希望有帮助;祝你好运!

简答题

让我感到困惑的是使用字符串文字作为类型。

字符串文本类型约束所有Promise<T>实现,以将[Symbol.toStringTag]的值设置为字符串"Promise"。

长示例

class MyPromise1<T> implements Promise<T> {
public readonly [Symbol.toStringTag] = "Promise"; // Allowed
public then = () => null; 
public catch = () => null;
}
class MyPromise2<T> implements Promise<T> {
public readonly [Symbol.toStringTag] = "Foobar"; // Error!
public then = () => null; 
public catch = () => null;
}
interface SomeThing<T> {
readonly [Symbol.toStringTag]: "Promise" | "Foobar";
}
class MySomeThing1<T> implements SomeThing<T> {
public readonly [Symbol.toStringTag] = "Promise"; // Allowed
}
class MySomeThing2<T> implements SomeThing<T> {
public readonly [Symbol.toStringTag] = "Foobar"; // Allowed
}
class MySomeThing3<T> implements SomeThing<T> {
public readonly [Symbol.toStringTag] = "Foobaz"; // Error!
}
interface OtherThing<T> {
readonly [Symbol.toStringTag]: string; 
}
class MyOtherThing<T> implements OtherThing<T> {
public readonly [Symbol.toStringTag] = "Any string is..."; // Allowed
}

最新更新