打字稿检查对象是否匹配类型

mar*_*595 5 typescript

我有以下问题。假设我有一个类型:

type A = {
    prop1: string,
    prop2: {
        prop3: string
    }
}
Run Code Online (Sandbox Code Playgroud)

我从外部服务接收一些 json 对象,我想验证该 json 是否匹配类型A

function isA(obj:any): boolean {
    // What should be here?
}
Run Code Online (Sandbox Code Playgroud)

所以如果我obj是这样的:

{
 prop1: "Hello",
 prop2: {
    prop3: "World"
 }
}
Run Code Online (Sandbox Code Playgroud)

或者

{
     prop1: "Hello",
     prop2: {
        prop3: "World"
     },
     moreProps: "I don't care about"
}
Run Code Online (Sandbox Code Playgroud)

该函数将返回真,但对于类似的东西会返回假

{
     foo: "Hello",
     bar: {
        prop3: "World"
     }
}
Run Code Online (Sandbox Code Playgroud)

实现这一目标的最简单方法是什么?

谢谢。

cas*_*ber 9

  1. 使用类型保护,以便 Typescript 也会在类型检查时为您缩小类型范围

要使用类型保护,您应该将isA函数的返回类型更改为obj is A

总的来说,这应该使您的类型验证函数看起来像:

function isA(obj: unknown): obj is A {
    // return boolean here
}
Run Code Online (Sandbox Code Playgroud)
  1. 使用typeof运算符检查属性

typeof将返回一个字符串值,告诉您变量的类型是什么。(文档

在这种情况下,对于 A 你可以这样做:

function isA(obj: unknown): obj is A {
    return (
        obj &&
        typeof obj === 'object' &&
        typeof obj['prop1'] === 'string' &&
        obj['prop2'] &&
        typeof obj['prop2'] === 'object' &&
        typeof obj['prop2']['prop3'] === 'string'
    );
}
Run Code Online (Sandbox Code Playgroud)

它不是世界上最易读的东西,如果您愿意,您可以随时将其分解为各个组成部分并对每个检查进行评论。

然而,需要注意的一件重要的事情是,typeof null实际上'object'您不能简单地检查 iftypeof obj['prop2'] === 'object'然后继续,您还需要检查它是否存在,因为它仍然可能是null

此时,您不仅可以在运行时正确验证,而且 TypeScript 现在还可以通过缩小返回 true 的类型来改进其类型obj检查。AisA

  • 我觉得很奇怪,没有比这更好的方法了......每次“A”改变时,它也需要改变。也很容易忘记添加属性。难道就没有更通用的方法吗?给定一个类型定义,如: ```type A = { prop1: string, prop2: { prop3: string } }``` 我认为该语言将提供一种简单的方法来检查某些内容是否满足该定义。不管怎样,谢谢你的回答。 (3认同)