string - typescript :强制类型为 "string literal"而不是 <string>

标签 string typescript literals branding

问题

Typescript 中是否有一种方法可以定义只有 string literal 的类型,不包括 string本身?

请注意,我不是在谈论某个字符串文字列表;为此,"Value1" | "Value2" 的简单联合,或 enum类型会起作用。我说的是任何字符串文字,但不是 string本身。

示例代码

type OnlyStringLiterals = ...; // <--- what should we put here?

const v1: OnlyStringLiterals = "hi"; // should work
const v2: OnlyStringLiterals = "bye"; // should work
// and so should be for any single string value assigned

// But:
const v3: OnlyStringLiterals = ("red" as string); // should NOT work -- it's string

用例

我在做Branding在我的代码中的类型上,我将一个品牌名称作为模板传递给我的父类。请参阅下面的代码:
abstract class MyAbstractClass<
    BRAND_T extends string,
    VALUE_T = string
> {
    constructor(private readonly _value: VALUE_T) { }

    getValue(): VALUE_T { return this._value; }

    private _Brand?: BRAND_T; // required to error on the last line, as intended!
}

class FirstName extends MyAbstractClass<"FirstName"> {
}

class AdminRole extends MyAbstractClass<"AdminRole"> {
}

class SubClassWithMissedName extends MyAbstractClass<string> {
   // I want this to error! ........................ ^^^^^^
}

function printName(name: FirstName) {
    console.log(name.getValue()); 
}

const userFirstName = new FirstName("Alex");
const userRole = new AdminRole("Moderator");

printName(userRole); // Already errors, as expected

Playground Link

我想确保每个子类都准确地传递一个 字符串文字 ,而不仅仅是 string到父类。

最佳答案

我找到了一个适用于我的用例的答案,但不是最可重用的。还是分享一下吧。

思考过程

我相信不可能用一种实体类型来表示我想要的东西,因为我什至无法想象如果我将鼠标悬停在 VS Code 上会出现什么!

但是,据我所知,Typescript 中有一个函数样式检查类型,您可以传入一个类型并期望返回一个类型,最后为其分配一个值以查看它是否通过。

使用通用类型和后续分配进行类型检查

使用这种技术,我正在考虑以下模板类型:

type TrueStringLiterals<T extends string> = string extends T ? never : true;

const v1 = "hi";
const check1: TrueStringLiterals<typeof v1> = true; // No error :-)

const v2 = "bye";
const check2: TrueStringLiterals<typeof v2> = true; // No error :-)

const v3 = ("red" as string);
const check3: TrueStringLiterals<typeof v3> = true; // Errors, as expected!

Playground Link

在已经通过的泛型类型中更容易

另外,在我的用例中,我正在做:
abstract class MyAbstractClass<
    BRAND_T extends (string extends BRAND_T ? never : string),
    VALUE_T = string
> {
...

Playground Link

...这就像一个魅力!

关于string - typescript :强制类型为 "string literal"而不是 <string>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60185084/

相关文章:

javascript - Javascript 中的通配符字符串比较

javascript - Firebase - 在 localStorage 对象有效时保持用户登录

typescript - 为什么 TypeScript 允许这样做?

java - 使用正则表达式将字符串数据的键和值格式化为 json 键值对

Java:从字符串中删除注释

javascript - 如何 switchmap - 发出包含原始可观察值和新可观察值的对象?

swift - #file 是否被视为 Swift 中的文字字符串?

java - Java 中的类型文字是什么?

reference - `&str` 可以包含指向 Rust 中程序内存的指针吗?

java - Java 11 中 String trim() 和 strip() 方法的区别