'不可分配给类型 never'使用类型谓词后

发布于 2025-01-16 18:45:22 字数 1264 浏览 0 评论 0原文

我正在尝试结合 创建强类型的技术带有类型谓词的字符串但失败,如以下代码所示: 输入图片这里的描述

错误是TS2339:属性'substr'在类型'never'上不存在,但解决这个问题正是工厂函数应该确保的:

export function isShortDateTimeWithSpaceDelimiter(
  datetime: string | ShortDateTimeWithSpaceDelimiter
): datetime is ShortDateTimeWithSpaceDelimiter {
  return DateTime.fromFormat(datetime, FORMAT_ISO_DATE_SPACE_DATE_TIME).isValid;
}

export function toShortDateTimeWithSpaceDelimiter(
  datetime: string
): ShortDateTimeWithSpaceDelimiter {
  if (isShortDateTimeWithSpaceDelimiter(datetime)) return datetime;
  throw new TypeError("Not a ShortDateTimeWithSpaceDelimiter");
}

因为TS假设工厂的返回类型是never,我想这没有按我的预期工作......我错过了什么?

类型定义如下所示:

// https://spin.atomicobject.com/2017/06/19/strongly-typed-date-string-typescript/
enum LocalDateTimeWithSpaceDelimiterBrand {}

/** Minute granularity: "yyyy-MM-dd hh:mm" */
export type ShortDateTimeWithSpaceDelimiter = string & LocalDateTimeWithSpaceDelimiterBrand;

I am trying to combine a technique for creating strongly typed strings with type predicates but failing, as the following bit of code shows:
enter image description here

The error is TS2339: Property 'substr' does not exist on type 'never', but fixing this is exactly what the factory function should have ensured:

export function isShortDateTimeWithSpaceDelimiter(
  datetime: string | ShortDateTimeWithSpaceDelimiter
): datetime is ShortDateTimeWithSpaceDelimiter {
  return DateTime.fromFormat(datetime, FORMAT_ISO_DATE_SPACE_DATE_TIME).isValid;
}

export function toShortDateTimeWithSpaceDelimiter(
  datetime: string
): ShortDateTimeWithSpaceDelimiter {
  if (isShortDateTimeWithSpaceDelimiter(datetime)) return datetime;
  throw new TypeError("Not a ShortDateTimeWithSpaceDelimiter");
}

Since TS assumes the return type from the factory is never, I guess this is not working as I had intended ... What am I missing?

The type definitions look like this:

// https://spin.atomicobject.com/2017/06/19/strongly-typed-date-string-typescript/
enum LocalDateTimeWithSpaceDelimiterBrand {}

/** Minute granularity: "yyyy-MM-dd hh:mm" */
export type ShortDateTimeWithSpaceDelimiter = string & LocalDateTimeWithSpaceDelimiterBrand;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

十六岁半 2025-01-23 18:45:22

它几乎没有提供任何实用性,因为它实际上从来没有提供过。我认为使用与品牌属性的典型交集在这里可以更好地充当名义打字。 (string & { __ShortDateTimeWithSpaceDelimiter__: 未知 })。但也许即使如此,这也不需要名义上的打字?无论如何,这是很大的开销,但收效甚微

It provides little to no utility because it's literally never. I think using a typical intersection with a branding property would work better here to serve as nominal typing. (string & { __ShortDateTimeWithSpaceDelimiter__: unknown }). But maybe even then this is does not need nominal typing? It is much overhead for little gain anyways ????

The type ShortDateTimeWithSpaceDelimiter is really just an alias for never, so it's practically useless and isn't as helpful as it should be when defining a different "type" of string.

There is also a playground example of nominal typing: playground

So here you could use string & { __brand: "ShortDateTimeWithSpaceDelimiter" }.

However I do suggest throwing all of this away altogether and stick with the simple string. Why is all of this necessary? Overkill occurs when types start being defined by code and act like code! Types should influence the design and implementation, not the other way around.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文