如何检查“未知”值的属性类型?

Beh*_*ooz 22 typescript

我有以下函数,它可能会收到一个未知值:

function formatReason(detail: unknown): string {
    if (detail
        && detail instanceof Object
        && detail.constructor.name === 'Object'
        && detail.hasOwnProperty('description')
        && typeof detail['description'] === 'number'
    ) {
        const output = detail['description'];
        return output;
    }

    return '';
}
Run Code Online (Sandbox Code Playgroud)

detail参数可以是任意值。如果它是一个具有description字符串类型属性的对象,则该函数应返回该属性值,否则返回空字符串。

首先,你建议使用anyunknown用于detail参数?

其次,无论我做什么, for 的类型output最终都是any. 我怎样才能确定它是string

Mat*_*hen 10

在实施此建议之前,没有一个很好的方法来编写此代码。与此同时,这取决于你是否喜欢anyunknown(如果你使用的是一些强制转换noImplicitAny,正如我通常建议的那样)。我不会担心局部变量的类型,output因为您已经声明了函数的返回类型string

  • 对于那些不想点击链接的人:`if (typeof x === 'object' && 'a' in x) { /** typed x allowed xa */}`。适用于 Typescript v4.9.5 (4认同)

Ale*_*lex 5

编辑:被霓虹灯纠正。打字机是不够的。我更新了示例以显式断言unknown值而不是隐式any.


我建议使用,unknown因为它是 的类型安全变体any,也就是说您可能想要使用类型保护来断言未知值。这会导致description您要查找的属性实际上被断言为 astring而不是any

打字员(见操场看看是什么IDescription):

public hasDescription(obj: unknown): obj is IDescription {
    return (obj as IDescription).description !== undefined
        && typeof (obj as IDescription).description === "string";
}
Run Code Online (Sandbox Code Playgroud)

在代码库中使用它会产生一个具有一些好处的 if 语句。

if (this.hasDescription(detail)) {
    // In this if-block the TypeScript compiler actually resolved the unknown type to the type described in the guard.
    console.log(detail.description);
}
Run Code Online (Sandbox Code Playgroud)

这是一个供您查看其工作原理的游乐场(请注意仅123输出到控制台的方式)。


您的特定问题的示例实现:

function formatReason(detail: unknown): string {
    if (this.hasDescription(detail) {
        return detail.description;
    }

    return '';
}

Run Code Online (Sandbox Code Playgroud)