此摘录来自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
}