经过查阅文档,似乎没有直接检查字符串数据类型最小/最大长度的方法。
但是,是否有一种使用自定义类型声明字符串数据类型的方法,以便检查字符串长度是否在给定范围内?
经过查阅文档,似乎没有直接检查字符串数据类型最小/最大长度的方法。
但是,是否有一种使用自定义类型声明字符串数据类型的方法,以便检查字符串长度是否在给定范围内?
你可以通过使用类型构造器和所谓的“幻影类型”( 在此处阅读有关此技术的优秀文章)来实现此目标,这是一种确保类型无法直接赋值给值的技术。
以下是使用这些技术的StringOfLength<Min,Max>
类型的示例:
type StringOfLength<Min, Max> = string & {
min: Min;
max: Max;
StringOfLength: unique symbol // this is the phantom type
};
// This is a type guard function which can be used to assert that a string
// is of type StringOfLength<Min,Max>
const isStringOfLength = <Min extends number, Max extends number>(
str: string,
min: Min,
max: Max
): str is StringOfLength<Min, Max> => str.length >= min && str.length <= max;
// type constructor function
export const stringOfLength = <Min extends number, Max extends number>(
input: unknown,
min: Min,
max: Max
): StringOfLength<Min, Max> => {
if (typeof input !== "string") {
throw new Error("invalid input");
}
if (!isStringOfLength(input, min, max)) {
throw new Error("input is not between specified min and max");
}
return input; // the type of input here is now StringOfLength<Min,Max>
};
// Now we can use our type constructor function
const myString = stringOfLength('hello', 1, 10) // myString has type StringOfLength<1,10>
// the type constructor fails if the input is invalid
stringOfLength('a', 5, 10) // Error: input is not between specified min and max
// The phantom type prevents us from assigning StringOfLength manually like this:
const a: StringOfLength<0, 10> = 'hello' // Type '"hello"' is not assignable to type { StringOfLength: unique symbol }
这里有一些限制 - 你不能阻止某人创建一个无效的类型,比如 StringOfLength<-1, -300>
,但是你可以添加运行时检查,确保传递给 stringOfLength
构造函数的 min
和 max
值是有效的。
编辑:在 TypeScript 中,这种技术现在更常被称为“品牌类型”。
接口或类型文字的属性,其类型为“唯一符号”类型,必须是“只读”的
。 - TOPKATreadonly
修饰符,应该能够解决该错误:readonly StringOfLength: unique symbol
。 - cdimitroulasstring
),而不是StringOfLength
。它还将防止您使用错误长度的字符串,例如StringOfLength <1,100>
不能分配给StringOfLength <1,50>
。 - cdimitroulasStringOfLength<x, y>
分配给 StringOfLength<a, b>
,其中 x != a
且 y != b
,但我没有看到任何编译错误。https://tsplay.dev/NnEExw - vighnesh153Min
和Max
类型参数也需要包含在最终类型中。https://tsplay.dev/mZZJKm - cdimitroulas