javascript - 在 typescript 中声明具有最小/最大长度的字符串类型

标签 javascript string typescript validation constraints

阅读文档后,似乎没有直接的方法来键入检查字符串数据类型的最小/最大长度。

但是,有没有办法使用一些自定义类型来声明字符串数据类型,以便它检查字符串长度是否在给定范围内?

最佳答案

您可以使用类型构造函数和称为“幻像类型”(read a nice article about this here) 的东西来实现这一点,这是一种确保类型不能直接分配给值的技术。

这是一个 StringOfLength<Min,Max> 的例子使用这些技术键入:

type StringOfLength<Min, Max> = string & {
  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>但您可以添加运行时检查 minmax传递给 stringOfLength 的值构造函数是有效的。

关于javascript - 在 typescript 中声明具有最小/最大长度的字符串类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51813272/

相关文章:

asp.net - 与IE6、7、8兼容且易于定制的JQuery Lightbox?

python - str.format(**arg) 可以用来检查格式吗?

javascript - 如何在保持分隔符的同时根据空格或符号拆分字符串?

angularjs - Angular 2. 在共享主机上运行

TypeScript 反射(reflect)元数据找不到名称 'Symbol'

javascript - 如何在 jqGrid 中的日期列中使用输入类型 ='date'

javascript - window.getSelection 在textarea中获取正确的选择

javascript - onclick 工作时 href 不工作

java - 迭代字符串时在输出中获取 Ljava.lang.String;@

angular - 模块解析失败 : *. ts 意外字符 '@'