如何将字符串强类型化为自定义数据类型



我使用字符串来表示我的数据并传递它。在使用它之前,我必须解析它并从字符串中获取数据。我不想在运行时检查解析错误。

我怎样才能给仅由工厂函数产生的字符串一个特殊类型,并确保它们在任何其他字符串类型上失败呢?

type MyData = string
let i = 0
function gen_id(): MyData {
return `hello__${i}`
}
function hello(_: MyData) {
console.log(_.split('__')[1])
}
hello(gen_id())
hello('world') // I want this to give compile error

目前不会产生编译错误。

TypeScript支持字符串模板字面值:

type MyData = `${string}__${number}`
let i = 0
function gen_id(): MyData {
return `hello__${i}`
}
function hello(_: MyData) {
console.log(_.split('__')[1])
}
hello(gen_id())
hello('world') // Argument of type '"world"' is not assignable to parameter of type '`${string}__${number}`'.(2345)

tsplayground

如何给仅由工厂函数产生的字符串一个特殊类型,并确保它们在任何其他字符串类型上失败?

你想要一个特殊的字符串,它只能来自于一个工厂函数。你描述的是字体标记。

你可以通过不包含只有该类型本身知道的内容而将其相交来创建一个标记类型。

一个品牌可能看起来像:

const idBrand = Symbol('idBrand')
type MyData = string & { [idBrand]: true }
// or: string & { __brand: 'fancystring' }
// or: string & { brand: idBrand }
// point is string & some spicy sprinkle.
// I like symbols as keys since they can't clash with any existing properties
// and you don't want them in autocomplete suggestions.
const brandedStringA: MyData = 'asdf' // error
const brandedStringB: MyData = 'asdf' as MyData // fine

这样你就可以创建一个像

这样的工厂:
let i = 0
function gen_id(): MyData {
return `hello__${i}` as MyData
}

如您所愿:

function hello(_: MyData) {
console.log(_.split('__')[1])
}
hello(gen_id()) // fine
hello('world') // error
hello('hello__123') // error

类型MyData的值仍然可以在string可以使用的任何地方使用,但是您不能将普通的string传递给需要MyData的东西。它必须来自工厂函数。

看到操场

最新更新