【问题标题】:Declaring string type with min/max length in typescript在打字稿中声明具有最小/最大长度的字符串类型
【发布时间】:2019-01-19 15:34:55
【问题描述】:

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

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

【问题讨论】:

  • 类型就是:类型。它们甚至在运行时都不存在了,这只是 JavaScript。类型无法检查字符串是否具有预期长度。你需要为此编写代码。
  • 取决于用例,但如果这是用于数据库存储,有很多类型验证库,如 Mongoose 的Schemas,可以开箱即用地做到这一点。如果你澄清你的用例,我相信你会得到更有针对性的建议。
  • @JBNizet 我知道静态类型检查在运行时没有帮助。但是当函数在代码中的其他地方被调用时,声明类型有助于检测错误的数据类型。而且由于 tsc 不仅充当类型检查器,而且充当转译器,我希望有一些解决方法来让这件事成为可能
  • @PatrickRoberts 我有一个非常简单的用例。只是一个以字符串为输入的函数。但我也想限制它的长度,如果我在通话期间违反该规则,我的编辑会警告我。我不认为有任何直接的解决方案,但有办法做到这一点会很好
  • 这仅适用于静态声明的字符串。对于来自用户输入或任何动态源的字符串,由于 JBNizet 解释的原因,这是不可能的,因此静态检查长度不是很有用。

标签: javascript string typescript validation constraints


【解决方案1】:

您可以使用类型构造函数和称为“幻象类型”(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&lt;-1, -300&gt; 这样的无效类型,但您可以添加运行时检查,以检查 minmax 值传递给 stringOfLength 构造函数函数有效。

【讨论】:

  • 它给我一个错误:A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'
  • 也许这是来自较新的 Typescript 版本的错误。如果添加 readonly 修饰符,它应该会删除错误:readonly StringOfLength: unique symbol
猜你喜欢
  • 2016-05-03
  • 2018-01-23
  • 2021-09-18
  • 1970-01-01
  • 2019-02-16
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多