如何确定 TypeScript 类型是否为文字字面量。

huangapple go评论62阅读模式
英文:

How to determine if a TypesScript type is a literal

问题

可能编写一个实用类型来确定一个类型是否为字面量吗?
例如:

type IsLiteral<T> ...
 
type IsStringALiteral = IsLiteral<string> // false
type IsStringLiteralALiteral = IsLiteral<'abc'> // true
type IsStringALiteral = IsLiteral<bool> // false
type IsStringLiteralALiteral = IsLiteral<false> // true
英文:

Is it possible to write a utility type to determine if a type is a literal?
e.g.

type IsLiteral&lt;T&gt; ...

type IsStringALiteral = IsLiteral&lt;string&gt; // false
type IsStringLiteralALiteral = IsLiteral&lt;&#39;abc&#39;&gt; // true
type IsStringALiteral = IsLiteral&lt;bool&gt; // false
type IsStringLiteralALiteral = IsLiteral&lt;false&gt; // true

答案1

得分: 0

以下是您提供的代码的中文翻译部分:

type IsString<T> = string extends T ? true : false;

type T = {
  true: true,
  123: 123,
  'text': 'text',
  string: string,
}
type X = {[K in keyof T]: IsString<T[K]>;}
// type X = {
//     true: false;
//     123: false;
//     text: false;
//     string: true;
// }
英文:

Related: https://stackoverflow.com/questions/52806230/determine-if-type-is-a-string-literal-number-literal-or-string-number-l

type IsString&lt;T&gt; = string extends T ? true : false;

type T = {
  true: true,
  123: 123,
  &#39;text&#39;: &#39;text&#39;,
  string: string,
}
type X = {[K in keyof T]: IsString&lt;T[K]&gt;}
// type X = {
//     true: false;
//     123: false;
//     text: false;
//     string: true;
// }

答案2

得分: 0

以下是您要翻译的内容:

回答自己的问题,因为我已经弄清楚了:

type IsUnion&lt;T, U extends T = T&gt; = T extends unknown ? ([U] extends [T] ? false : true) : false;
type IsStringLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends string ? (string extends A ? false : true) : false;
type IsNumberLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends number ? (number extends A ? false : true) : false;
type IsBooleanLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteral&lt;A&gt; = IsStringLiteral&lt;A&gt; extends true ? true : IsNumberLiteral&lt;A&gt; extends true ? true : IsBooleanLiteral&lt;A&gt; extends true ? true : false;

请注意,我在这里包含了IsUnion的功能,因为在我的情况下,我想要:

type IsStringUnionALiteral = IsLiteral&lt;&#39;a&#39; | &#39;b&#39;&gt; // false

如果这不符合您的要求,那么可以如下:

type IsStringLiteral&lt;A&gt; = A extends string ? (string extends A ? false : true) : false;
type IsNumberLiteral&lt;A&gt; = A extends number ? (number extends A ? false : true) : false;
type IsBooleanLiteral&lt;A&gt; = A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteral&lt;A&gt; = IsStringLiteral&lt;A&gt; extends true ? true : IsNumberLiteral&lt;A&gt; extends true ? true : IsBooleanLiteral&lt;A&gt; extends true ? true : false;
英文:

Answering my own question here, since I've figured it out:

type IsUnion&lt;T, U extends T = T&gt; = T extends unknown ? ([U] extends [T] ? false : true) : false;
type IsStringLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends string ? (string extends A ? false : true) : false;
type IsNumberLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends number ? (number extends A ? false : true) : false;
type IsBooleanLiteral&lt;A&gt; = IsUnion&lt;A&gt; extends true ? false : A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteral&lt;A&gt; = IsStringLiteral&lt;A&gt; extends true ? true : IsNumberLiteral&lt;A&gt; extends true ? true : IsBooleanLiteral&lt;A&gt; extends true ? true : false;

Note here I have included IsUnion functionality because in my case I want:

type IsStringUnionALiteral = IsLiteral&lt;&#39;a&#39; | &#39;b&#39;&gt; // false

If that doesn't suit your requirements, then it would be as follows:

type IsStringLiteral&lt;A&gt; = A extends string ? (string extends A ? false : true) : false;
type IsNumberLiteral&lt;A&gt; = A extends number ? (number extends A ? false : true) : false;
type IsBooleanLiteral&lt;A&gt; = A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteral&lt;A&gt; = IsStringLiteral&lt;A&gt; extends true ? true : IsNumberLiteral&lt;A&gt; extends true ? true : IsBooleanLiteral&lt;A&gt; extends true ? true : false;

huangapple
  • 本文由 发表于 2023年7月13日 14:49:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76676620.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定