如何在设置变量时强制使用严格类型?

huangapple go评论69阅读模式
英文:

How to enforce strict typing when setting a variable?

问题

以下是你要翻译的内容:

我想要确保我从一个YAML文件中读取的数据与它要赋给的变量的类型一致

type Http = {
  name: string
  api: string
  resp: number
  status: string
  statusEffective: string
}

export const monitorHttp = () => {
  const conf = getConf("conf-http.yml") as Http[]
  log.info("", conf)
}

getConf 的定义如下:

export const getConf = (file: string) => {
  try {
    return yaml.load(fs.readFileSync(`../data/${file}`, "utf8"))
  } catch {
    log.error("无法加载config.yaml,中止")
    process.exit(1)
  }
}

因此,getConf 返回的类型是 any,因为不同的.yml文件可能有不同的结构。

我原本期望通过将 conf 强制转换为 Http[] 来只接受具有此结构的数据。

然而,事实并非如此,即使发送了在 Http 中不存在的字段,程序仍然正常运行。使用包含以下内容的YAML文件:

- name: jellyfin
  api: http://jellyfin.xxxx
  resp: 200
  status: enabled
  wazaa: wazii

我得到了如下结果:

2023-02-26 17:55:49.979 INFO    \W\dev-perso\hass-monitoring\src\monitor-http.ts:14         [
  {
    name: 'jellyfin',
    api: 'http://jellyfin.xxxx',
    resp: 200,
    status: 'enabled',
    wazaa: 'wazii'
  }
]

尽管 wazaaHttp 中不存在,为什么程序仍然正常运行呢?或者更具体地说:如何在初始化或更新变量时强制执行严格的类型检查?

英文:

I would like to ensure that the data I read from a YAML file is aligned with the type of the variable it goes into:

type Http = {
  name: string
  api: string
  resp: number
  status: string
  statusEffective: string
}

export const monitorHttp = () => {
  const conf = getConf("conf-http.yml") as Http[]
  log.info("", conf)
}

getConf is defined as

export const getConf = (file: string) => {
  try {
    return yaml.load(fs.readFileSync(`../data/${file}`, "utf8"))
  } catch {
    log.error("cannot load config.yaml, aborting")
    process.exit(1)
  }
}

What is therefore returned by getConf is of type any there will be various structures for different .yml files).

I was expecting that by coercing conf to be Http[] only data with this structure would be accepted.

It is not true however, by sending fields that do not exist in Http the program still runs fine. With a YAML file containing

- name: jellyfin
  api: http://jellyfin.xxxx
  resp: 200
  status: enabled
  wazaa: wazii

I get the result

2023-02-26 17:55:49.979 INFO    \W\dev-perso\hass-monitoring\src\monitor-http.ts:14         [
  {
    name: 'jellyfin',
    api: 'http://jellyfin.xxxx',
    resp: 200,
    status: 'enabled',
    wazaa: 'wazii'
  }
]

Why does the program run fine despite wazaa not existing in Http? Or, more specifically: how to enforce a strict type checking when initializing or updating a variable?

答案1

得分: 1

没有模式,yaml.load 无法知道它应该读取什么,因此它会解析并返回任何有效的 YAML。在 TypeScript 中的类型强制转换并不验证任何内容,而只是告诉编译器知道类型是什么。

更重要的是,如果你想确保输入具有特定的结构和类型,你要么需要自己验证数据,要么使用一个可以为你执行验证的库。

英文:

Without a schema, yaml.load cannot know what it is expected to read, so it will parse and return anything that is valid yaml. Type coercion in TS doesn't validate anything, instead it just communicates to the compiler that you know what the type is.

More to the point, if you want to ensure that your input has a given structure and type, you either need to validate the data yourself or use a library that does that for you.

答案2

得分: 1

你可以使用 zod 库进行运行时验证。

你需要在与 TypeScript 稍微不同的语言中定义一个模式,然后你将自动获得一个 TypeScript 类型以及一个用于根据此模式解析任意值的函数。

英文:

You can use the zod library for runtime validation.

You'll need to define a schema in a slightly different language than Typescript, and then you'll automatically get a Typescript type and a function for parsing an arbitrary value against this schema.

huangapple
  • 本文由 发表于 2023年2月27日 02:09:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75574036.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定