33

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

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 '';
}

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

首先,您是否建议使用anyunknown作为detail参数?

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

4

3 回答 3

12

编辑:由霓虹灯纠正。typeguard 还不够。我更新了示例以显式断言一个unknown值而不是一个隐含的any.


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

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

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

在代码库中使用它会产生一个具有一些好处的 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);
}

这是一个让您了解其工作原理的游乐场(请注意如何仅123将其输出到控制台)。


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

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

    return '';
}

于 2019-04-19T10:44:25.573 回答
6

在实施此建议之前,没有编写此代码的好方法。同时,您是否喜欢anyunknown(如果您使用noImplicitAny,请使用一些演员表,我通常会推荐)取决于您。我不会担心output局部变量的类型,因为您已经声明了函数的返回类型string

于 2018-08-01T01:43:04.587 回答
0

这真的应该内置到打字稿中!

无论如何,这是我稍微更通用的变体,如果存在,它将返回属性的字符串值。

function getStrProp(o: unknown, prop: string): string | unknown {
    try {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const p = (o as any)[prop]
        if (typeof p === 'string') {
            return p
        }
    } catch {
        // ignore
    }
    return undefined
}

如果用于错误处理,我的典型用例

try {
    httpServer = https.createServer(...)...
} catch (err) {
    if (getStrProp(err, 'code') === 'ENOENT') {
        throw 'HTTPS certificates missing: ' + getStrProp(err, 'message')
    }
于 2021-11-19T08:38:15.740 回答