字符串和字符串文字的 TypeScript 联合 [英] TypeScript union of string and string literals

查看:40
本文介绍了字符串和字符串文字的 TypeScript 联合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为一个已知的字符串文字或任何字符串创建一个类型定义,例如:

type IColor = "blue" |绿色" |红色" |细绳;

TS 不会抱怨那个类型定义,但它也无助于智能感知.我的目标是定义一个接受已知颜色之一或任何颜色字符串的函数.

const knownColors = {绿色:#66bb6a",红色:#ef9a9a",蓝色:#81d4fa",} 作为常量;function getColor(color: keyof typeof knownColors | string): string {如果(已知颜色中的颜色)返回 knownColors[color as keyof typeof knownColors];返回颜色;}

用法:

getColor("blue");//"blue" 是已知颜色,返回 "#81d4fa"getColor("黑色");//"black" 不是已知颜色,返回 "black"

我希望intellisense变得智能

getColor("_//当我输入这一行时,^ blue//我想要这些建议^ 绿色^ 红色

解决方案

这目前被认为是设计限制(请参阅

<小时>

类型签名可能比您希望的更令人困惑.你也可以通过使用

<小时>

好的,希望有帮助!

游乐场连结代码

I'd like to create a type definition for one of known string literals, or any string, e.g:

type IColor = "blue" | "green" | "red" | string;

TS doesn't complain about that type definition, but it also doesn't help with intellisense. My goal would be to define a function that accepts one of known colors or any color string.

const knownColors = {
    green: "#66bb6a",
    red: "#ef9a9a",
    blue: "#81d4fa",
} as const;

function getColor(color: keyof typeof knownColors | string): string {
   if (color in knownColors) 
      return knownColors[color as keyof typeof knownColors];

   return color;
}

Usage:

getColor("blue");    // "blue" is a known color, returns "#81d4fa" 
getColor("black");   // "black" is not a known color, returns "black"

I want intellisense to be intelligent

getColor("_          // as I type this line, 
          ^ blue     // I want these suggestions
          ^ green
          ^ red 

解决方案

This is currently considered a design limitation (see microsoft/TypeScript#29729) and/or a missing feature (see microsoft/TypeScript#33471) of TypeScript. From the type system's point of view, string is a supertype of any string literal like "blue" or "red", and so a union string | "blue" | "red" is the same as string and the compiler aggressively reduces such unions to string. This is completely correct as far as type safety goes. But it's not great from the point of view of documentation or IntelliSense, as you've seen.

Luckily the linked TypeScript issues suggest some workarounds which you might find useful. One is to represent the union type in a way that the compiler does not aggressively reduce. The type string & {} is conceptually the same as string, since the empty type {} matches any non-null and non-undefined type. But the compiler does not perform this reduction (at least as of TS 3.8). From this type you can build your union like (string & {}) | "red" | "green" | "blue", and the compiler will keep this representation long enough to give you IntelliSense hints:

function getColor(color: (keyof typeof knownColors) | (string & {})): string {
    if (color in knownColors)
        return knownColors[color as keyof typeof knownColors];
    return color;
}

This accepts and rejects the same inputs as before:

getColor("red"); // okay
getColor("mauve"); // okay
getColor(123); // error

But you can verify that IntelliSense produces the following:


The type signature might be a little more confusing than you'd like. You could also get a similar effect by using overloads instead:

function getColorOvld(color: (keyof typeof knownColors)): string;
function getColorOvld(color: string): string;
function getColorOvld(color: string): string {
    if (color in knownColors)
        return knownColors[color as keyof typeof knownColors];
    return color;
}

getColorOvld("red"); // okay
getColorOvld("mauve"); // okay
getColorOvld(123); // error

This also gives you reasonable IntelliSense:


Okay, hope that helps!

Playground link to code

这篇关于字符串和字符串文字的 TypeScript 联合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆