gpt4 book ai didi

typescript - Typescript 中变量的动态字符串文字类型

转载 作者:行者123 更新时间:2023-12-02 02:18:17 25 4
gpt4 key购买 nike

我从身份验证提供商处获取带有声明的 token 。它是一个如下所示的 JSON 对象:

{
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c8bdbbadba88adb0a9a5b8a4ade6a7baaf" rel="noreferrer noopener nofollow">[email protected]</a>",
"urn:dev:claims/user-id": "123"
}

我正在尝试在客户端上创建一个代表性界面或类型以正确访问此 token key 。问题是上面“urn:dev:claims/user-id”的“dev”部分是动态的,它来自环境变量,如下所示:

const ClaimKey = urn:${process.env.REACT_APP_ENV}:claims/user-id

当我尝试以下操作时:

interface MyInterface {
email: string;
[claimKey]: string;
}

它不起作用。

这是一个完整的可重现示例:

const env = {
REACT_APP_ENV: "dynamic-value"
}

const token = {
"email": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="443137213604213c25293428216a2b3623" rel="noreferrer noopener nofollow">[email protected]</a>",
"urn:dev:claims/user-id": "123"
}

const claimKey = `urn:${env.REACT_APP_ENV}:claims/user-id`

interface MyInterface {
email: string;
[claimKey]: string;
}

最佳答案

TypeScript 目前无法完全满足您的要求:

  • 您希望编译器处理 process.env.REACT_APP_ENV作为一些“未知但独特”string从字面上看,就像 unique symbol 一样适用于 symbol -键入的值。 microsoft/TypeScript#33038 有一个实验性拉取请求这将允许像 unique string 这样的事情,但它从未进入语言。

  • 此外,您需要能够将该唯一字符串连接到其他字符串文字并获得某种唯一的输出;也许这还需要支持 unique stringmicrosoft/TypeScript#40598 中实现的“模式”模板文字类型内部,而且这是否有效并不明显。

  • 即使这一切都已解决,您目前也不能使用模式模板文字类型作为对象键;请参阅 microsoft/TypeScript#42192 。类似 Record<`foo${string}`, number> 的对象类型不幸的是,它的待遇非常像 {} ;如果您指定类似 {fooOops: "This is not a number"} 的类型,它不会提示 (好吧,至少这部分在 TS4.4 中是固定的;模式模板文字可以按照 microsoft/TypeScript#44512 在索引签名中使用)

所有这些加在一起意味着从 TS 4.4 开始,这不属于 TypeScript 的可能性范围。


相反,您需要某种解决方法。我正在尝试使用 string enum 模拟 string 的不透明/名义子类型它与键一起使用,但它实际上并没有比我确定的解决方法更有用:占位符字符串文字类型,如 "###${process.env.REACT_APP_ENV}###"我们假装process.env.REACT_APP_ENV 的已知实际类型。只要我们只将类型称为 process.env.REACT_APP_ENV而不是假装的字符串文字,一切都会成功。我们甚至可能希望假值类似于 "!!!PLACEHOLDER_DO_NOT_USE_THIS!!!"或者任何你需要说服人们不要使用文字类型的东西。

它看起来像这样:

declare const process: {
env: {// the following type is a fiction but is the best I can do
REACT_APP_ENV: "###${process.env.REACT_APP_ENV}###"
}
}

然后是你的claimKey将是 const -asserted模板字符串,以便编译器可以连接它并保持它的字符串文字性:

const claimKey = `urn:${process.env.REACT_APP_ENV}:claims/user-id` as const

一切都按预期工作,主要是:

interface MyInterface {
email: string;
[claimKey]: string;
}

const myInterface: MyInterface = {
email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ea9f998f98aa8f928b879a868fc485988d" rel="noreferrer noopener nofollow">[email protected]</a>",
[claimKey]: "123"
}
万岁!不过,这只是一个解决方法。不幸的是,该占位符值可能会显示为 IntelliSense 提示:

const booIntelliSense: MyInterface = {
email: "",
"urn:###${process.env.REACT_APP_ENV}###:claims/user-id": "oops" // <-- hinted by IntelliSense!
}

所以它确实不完美。哦,好吧。

Playground link to code

关于typescript - Typescript 中变量的动态字符串文字类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66841911/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com