这个 TypeScript 技巧将让你大开眼界

TypeScript 是一个强大的工具,可以确保代码的类型安全性。通过使用 ​​ExtractSurname​​ 类型,我们能够确保 ​​findName​​ 函数只接受有效的姓氏,从而避免拼写错误和潜在的运行时错误。

TypeScript 是一个强大的工具,可以确保代码的类型安全性。通过使用 ​​ExtractSurname​​ 类型,我们能够确保 ​​findName​​ 函数只接受有效的姓氏,从而避免拼写错误和潜在的运行时错误。

这个 TypeScript 技巧将让你大开眼界

TypeScript 是一个了不起的工具,可以用来操纵现有数据并开发出优秀的实践方法。

今天我们将探索如何从字符串数组中正确提取全名,以确保输出的类型安全和干净。

问题

我们检查一下这段代码并理解它的问题:

const names = ["Daniel Craciun", "John Doe", "Harry Pigeon"]

const findName = (surname: string) => {
  return names.find((name) => name.includes(surname))
}

// 我们可以传入任意字符串,这是不理想的。

console.log(findName("Craciun")) // 输出: Daniel Craciun
console.log(findName("Doee")) // 输出: undefined

这段代码使用了一个名字数组进行搜索。findName 函数接受一个姓氏字符串并返回相关的全名。问题在于当你输入"Doee"进findName函数时会出现。

这个不起眼的拼写错误会导致undefined输出,这可能会在后续导致错误,因为没有任何机制阻止我们犯这个错误。

这时 TypeScript 就派上用场了。

如果我们确保findName只接受字面的姓氏,即Craciun,Doe,Pigeon,那么当我们输入names数组中不存在的输入(如 "Doee")时,编译器就会报警。

解决方案

我们已经确定,findName的有效参数需要包含所有现有的姓氏。为了实现这一点,我们创建一个名为ExtractSurname的泛型类型。

ExtractSurname的代码可能看起来很复杂,但我们将逐步解析它:

type ExtractSurname<T extends string> = T extends `${infer Firstname} ${infer Surname}` ? Surname : null

这里ExtractSurname接受一个泛型参数T,该参数使用extends操作符指的是任何字面字符串。

在ExtractSurname<"Daniel">中,T的值等于"Daniel"。

接下来我们应用 TypeScript 的三元操作符,这类似于 JavaScript 的三元操作符,但我们比较的是类型而不是实际数据。

我们知道names数组的格式是“<Name> <Surname>”,所以这里的infer关键字从 T 中提取子类型。

在ExtractSurname<"Daniel Craciun">中:

infer Firstname = "Daniel"
infer Surname = "Craciun"

最后,如果输入满足我们的 “” 格式,则返回姓氏作为类型,否则返回 null

好了,我们的ExtractSurname类型已经准备好了。

现在我们需要一个Surname类型来表示names中的所有姓氏。

type ExtractSurname<T extends string> = T extends `${infer Firstname} ${infer Surname}` ? Surname : null

const names = ["Daniel Craciun", "John Doe", "Harry Pigeon"] as const
type Surname = ExtractSurname<(typeof names)[number]>

names满足 ExtractSurname 的“<Name> <Surname>”格式。

我们使用as const将names的类型缩小为字面字符串数组。这意味着我们将names的类型从string强制转换为:

readonly ["Daniel Craciun", "John Doe", "Harry Pigeon"]

参数(typeof names)[number] 表示names中每个索引元素的类型:

"Daniel Craciun" | "John Doe" | "Harry Pigeon"

最后,这是 Surname 的结果类型:

type of Surname: "Craciun" | "Doe" | "Pigeon"

最后一步是更新我们之前定义的findName函数,用一个新的findNameUsingSurname函数,如下所示:

// 接受实际的 `Surname` 而不是一般的字符串。
const findNameUsingSurname = (surname: Surname) => {
  // 注意:我们需要后缀操作符 "!" 来断言 `find` 函数不会返回 undefined 值。
  return names.find((name) => name.includes(surname))!
}

// 唯一可接受的输入:"Craciun", "Doe", "Pigeon" = 最大类型安全
const fullName = findNameUsingSurname("Craciun")

// 输出: "Daniel Craciun"
console.log(fullName)

这就是我们预期的 TypeScript 编译器的魔法:

结论

TypeScript 是一个强大的工具,可以确保代码的类型安全性。通过使用ExtractSurname类型,我们能够确保findName函数只接受有效的姓氏,从而避免拼写错误和潜在的运行时错误。这个技巧不仅提高了代码的安全性,还增强了开发效率。希望你能在项目中尝试这个技巧,并体验它带来的便利和强大功能。

©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经

(0)
打赏 微信扫码打赏 微信扫码打赏 支付宝扫码打赏 支付宝扫码打赏
清一色的头像清一色管理团队
上一篇 2024年6月6日 17:02
下一篇 2024年6月6日 17:02

相关推荐

发表评论

登录后才能评论

联系我们

在线咨询:1643011589-QQbutton

手机:13798586780

QQ/微信:1074760229

QQ群:551893940

工作时间:工作日9:00-18:00,节假日休息

关注微信