英文:
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'
}
]
尽管 wazaa
在 Http
中不存在,为什么程序仍然正常运行呢?或者更具体地说:如何在初始化或更新变量时强制执行严格的类型检查?
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论