我想确保我从 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("cannot load config.yaml, aborting")
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
中不存在,程序却能正常运行?或者,更具体地说:如何在初始化或更新变量时强制执行严格的类型检查?
没有模式,
yaml.load
无法知道它期望读取什么,因此它将解析并返回任何有效的 yaml。 TS 中的类型强制不验证任何内容,而只是向编译器传达you知道类型是什么。
更重要的是,如果你想确保你的输入具有给定的结构和类型,你要么需要自己验证数据,要么使用一个库来为你做这件事。
您可以使用 zod 库进行运行时验证。
您需要使用与 Typescript 略有不同的语言定义模式,然后您将自动获得一个 Typescript 类型和一个用于根据该模式解析任意值的函数。