带占位符的模板文字类型的子类型规则是什么(如`${number}em`
)?它不在手册的Template Literal Types部分中,我在搜索中也没有找到任何与它相关的东西,尽管我可能在哪里错过了它;搜索它是很棘手的.
我之所以这样问,是因为我最近惊讶地发现`${number}` extends `${string}`
是真的.经过反思,我有一个合理的 idea 为什么会这样,但我正在寻找确认和细节,如果我是对的,或者如果我错了,我正在寻找正确的解释.(作为背景,这是在我试图向自己证明我对this question的答案是可靠的时候提出的.)
我的 idea 是:
- 如果匹配
S
的字符串也匹配T
,则模板文字类型S
是模板文字类型T
的子类型.
对于我的`${number}` extends `${string}`
示例也是如此,因为匹配`${number}`
(如"123"
)的任何字符序列也将匹配`${string}`
.
这似乎也是the general rule和"...any term of type 101 can safely be used in any context where a term of type 102 is expected..."之间的合理契合.
这是正确的吗?如果是这样,是否还有进一步的细微差别?如果不是,正确的定义是什么?
顺便说一句,以下是我用来测试直觉的一系列有点曲折的测试:
type A = `${number}` extends `${number}` ? true : false;
// ^?
// true, since they're the same thing, so yeah, it's a match
type B = `${number}` extends `${number|string}` ? true : false;
// ^?
// true, anything matching `${number}` would also match `${number|string}`
type C = `${number}` extends `${string}` ? true : false;
// ^?
// true, which makes sense for a template literal even though number isn't a subtype of
// string, because anything matching `${number}` would also match `${string}` --
// that is, a series of digits is not just a valid number, but also a valid string
type D = `${string}` extends `${number}` ? true : false;
// ^?
// false, because the converse isn't true; not all sequences of characters are
// valid numbers
type E = `${number|string}` extends `${number}` ? true : false;
// ^?
// false - same as D, basically
type F = `${number}` extends `${string}${number}` ? true : false;
// ^?
// false because something matching `${number}` wouldn't match `${string}${number}`
type G = `${string}${number}` extends `${string}${number}` ? true : false;
// ^?
// true, they're the same thing
type H = `${number}${string}` extends `${string}${number}` ? true : false;
// ^?
// false, for the same reason as D and E
type I = `${number}x` extends `${string}x` ? true : false;
// ^?
// true - basically the same as C, just with an x on it
type J = `${number}x` extends `${string}y` ? true : false;
// ^?
// false because something matching `${number}x` wouldn't match `${string}y`