如何在不使用 as 的情况下确保 TypeScript string|string[] 是字符串?

2023-11-22

edit
由于时间的推移,这个问题从对此的评论和回答看来,它已经失去了有效性。尽管最初出现,但它并不是这个的骗局。

我有一个翻译功能,通过以下签名工作。

getI18n(id: string) : string { ... }

我注意到输入以下内容有点乏味。

const titles = [
  this.util.getI18n("Donkey"),
  this.util.getI18n("Monkey"),
  ...
  this.util.getI18n("Wonkey")
];

我更喜欢使用这样的东西。

const titles = this.util.getI18n(["Donkey", "Monkey", ..., "Wonkey"]);

所以我引入了一个接受的函数string and string[]带有以下签名。

getI18n(id: string | string[]) : string | string[] { ... }

这感觉很天才,直到我注意到我必须为愚蠢的打字稿解释结果是string而不是一些胡言乱语字符串或字符串数​​组东西,以这个结束(对于非数组翻译)。

someValue.replace("xxx", this.util.getI18n("Donkey") as string);

有没有办法解释 TypeScript 的输出is string即使它可能string[]在其他情况下?


您可以通过泛型类型属性来达到效果。考虑:

function getI18n<A extends string[] | string>(id: A): A { 
    return id; // example implementation
}

const arr = getI18n(['a', 'b']) // arr is string[]
const str = getI18n('a') // str is string

通用方法的缺点

由于该解决方案对于 id 函数非常有效,因此问题从任何实现开始,TS 抱怨类型,就好像唯一的方法是在不进行任何修改的情况下传递参数。 考虑:

function getI18n<A extends string[] | string>(id: A): A { 
    if (typeof id === 'string') {
        return id.concat('suffix') as A; 
    } else {
        return (id as string[]).map(x => x.concat('suffix')) as A;
    }
}

该解决方案效果很好,但我们需要考虑一些事情:

  • 类型断言需要在函数体中使用
  • 代码没有很好地显示什么输入类型映射到什么输出(重载表明)
  • 输出的类型推断将错误地推断输入的类型

最后一点问题可以在下面的示例中查看:

const str = getI18n('a') // str is type "a"

所以输出类型是“a”,但在示例中实现结果将是字符串“asuffix”,因此类型是错误的。

不要这样做,函数应该有一种输入类型

我想在整个主题中添加一件事。事实上,我们对这种多态输入的需求通常是通过常见的 JS 方法继承的,如果这样的事情被认为是历史上的良好实践。但实际上,具有特定一种输入的函数会更好,它会产生更少的混乱和问题。

创建具有单态类型的函数。

function getI18n(ids: string[]): string[] { 
    return ids.map(id => id + "suffix");
}

const arr = getI18n(['a', 'b'])
const str = getI18n(['a'])

就那么简单。该方法的优点:

  • 类型级别没有条件
  • 价值水平没有条件
  • 没有问题 - 对于这样那样的输入 f 会返回什么

将字符串放入数组括号中实际上没有任何成本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在不使用 as 的情况下确保 TypeScript string|string[] 是字符串? 的相关文章

随机推荐

  • 以编程方式从共享邮箱发送 Outlook 电子邮件

    我正在尝试使用 python 从共享邮箱发送电子邮件 我已经能够通过自己的电子邮件成功发送它 但是使用共享邮箱 我已经测试过我也可以访问 发送邮件给我带来了问题 python 中用于电子邮件脚本的代码 import win32com cli
  • Postgresql 中的 JSON 输出

    我希望我没有遗漏一些非常明显的东西 我想从 postgres 函数获取 JSON 输出 我想许多其他函数已经需要这个 并且我很乐意在我的服务器上安装 contrib 函数的扩展 有没有办法从 sql 或 plpgsql 函数获取 JSON
  • 停止从 IIS 7.5 中的父 ASP.NET 应用程序继承 web.config

    我们在 IIS 7 5 中部署了 ASP NET 网站 应用程序 1 然后在该应用程序下创建另一个 ASP NET 应用程序 应用程序 2 但在App 2中 我不想继承web config来自应用程序 1 如果我尝试在 App 1 中执行以
  • 有没有办法以编程方式关闭 WPF 中的菜单项

    我在 wpf 中有一个菜单 上面有一个输入框和一个按钮 一旦用户单击按钮 我需要关闭菜单 有没有办法做到这一点 menu menu
  • C++中的非静态函数可以修改静态变量吗

    C 中的非静态函数可以修改静态变量吗 是的 只要数据成员的可见性允许 非静态成员函数就可以修改静态数据成员
  • 运行 tweepy 的 Airflow 任务退出并返回代码 -6

    我有一个简单的 Airflow DAG 它只有一个任务 stream from twitter to kafka 以下是 DAG 的代码 default args owner me depends on past False start d
  • 如何知道适合固定大小的 UILabel 的 NSString 长度?

    我知道 NSString 有确定其帧大小的方法 使用 NSString UIKit Additions sizeWithFont 反过来又如何呢 我的意思是 如果我有固定的框架大小 我如何知道 NSString 可以容纳多少个字符或单词 如
  • Pods 依赖项的 Xcode 10 多个命令构建错误

    Multiple commands produce Users abc Library Developer Xcode DerivedData MyProject cworwzaxajsmfkcfvourofovbggd Build Pro
  • 错误:静态成员函数中的成员使用无效

    我有两个类 这是其中一个类的标题 ifndef WRAPPER HPP define WRAPPER HPP include
  • 跳过调试器中的当前行

    有没有办法使用键盘快捷键跳过 Visual Studio 调试器中的当前行 我能够做到这一点的唯一方法是使用左侧的黄色光标或 设置下一个语句 这在函数末尾不起作用 设置下一条语句 CTRL SHIFT F10 快捷方式将在函数末尾起作用 但
  • 谷歌地图与离子

    我正在尝试使用 google 地图和 Ionic 来实现地图 我按照这个编码Link但我得到的只是一个空白屏幕 不知道哪里出了问题 请帮忙 这是控制器 angular module starter ionic controller MapC
  • 如何从日期时间创建日期(使用 lubridate)?

    假设我创建了一个包含日期和时间的变量 a lt ymd hms 2014 01 01 12 23 34 如何创建另一个只有日期的变量 也就是我应该怎么做才能转型a的值等于b的值在哪里b is b lt ymd 2014 01 01 你可以只
  • 如何在按下返回键时快速隐藏键盘?

    I am using UITextfied while clicking on textfied keyboard appear but when i pressed the return key keyboard is not disap
  • password_hash、password_verify、MySQL的误解?

    我似乎无法让这个测试显示数据库中的哈希密码 它可以很好地显示表单中的密码 尝试进行此测试以找出为什么我无法将表单中的密码与数据库中存储的密码进行比较来验证密码 我读到了一些关于转义哈希中的 符号的内容 但我不确定如何使用我正在使用的代码来做
  • locale什么时候影响R的正则表达式?

    R 有几个用于正则表达式的特殊的与语言环境无关的字符类 From regex alnum 表示 0 9A Za z 后者除外 取决于区域设置和字符编码 而 前者独立于区域设置和字符集 我想知道何时会出现特定于区域设置的问题 我根据中的信息尝
  • Powerpoint:手动设置幻灯片名称

    Context C 中的 PowerPoint 幻灯片有一个属性 Slide Name 通常包含任意字符串值 在我的 C 应用程序中 我想使用此属性来识别幻灯片 幻灯片顺序不可靠 问题 如何在 PowerPoint 应用程序中手动设置 Sl
  • 免费网络监控器

    我在集成两种产品时遇到问题 其中一种是我的 但它们似乎没有说话 所以我想确保他们的沟通正确 我查看了网络监视器并发现了 TCP Spy 这有效 但一次只显示对话的一侧 它必须在本地运行 我理想情况下希望同时看到双方 但你不能运行 TCP S
  • 在 Ruby 中实现同步屏障

    我正在尝试 复制 CUDA 的行为 synchtreads Ruby 中的函数 具体来说 我有一组N需要执行某些代码的线程 然后在继续执行其余业务之前 所有线程都在执行中点互相等待 例如 x 0 a Thread new do x 1 sy
  • wait_fences:未能收到回复:10004003 - 什么?

    一直收到这个奇怪的错误 事情是这样的 在下面的方法中 我会出现一个警报视图 获取 U N 和 PW 然后尝试启动另一个方法 方法 postTweet 没有被激活 我刚刚在控制台中收到此错误 wait fences failed to rec
  • 如何在不使用 as 的情况下确保 TypeScript string|string[] 是字符串?

    edit由于时间的推移 这个问题从对此的评论和回答看来 它已经失去了有效性 尽管最初出现 但它并不是这个的骗局 我有一个翻译功能 通过以下签名工作 getI18n id string string 我注意到输入以下内容有点乏味 const