内联条件打字机

时间:2017-11-30 05:25:11

标签: typescript

我希望能够为我的类的一个参数接受字符串或错误,但是然后有一个类型保护,这样当我使用内联条件来检查类型时,它会编译。

似乎不支持内联条件的类型控制,如下面的三个示例所示,只有最后一个编译。

当我说&#34;内联条件&#34;时,我指的是(<boolean statement>)? a : b形式,而不是多行if / else块,由于某种原因被称为&#34; inline&#34;在documentation

更新:这更多地与javascript相比,而不是打字稿,它确实支持内联条件的类型保护

export class MyError extends Error {
    public code; name; message

    constructor(code: number = -1, name: string = '', err?: Error | string) {
        super()
        this.name = name
        this.code = code 
        // no type guards
        this.message = this.name + (err)? ": " + (err instanceof Error)? err.message : err : ''
    }
}

export class MyError2 extends Error {
    public code; name; message

    constructor(code: number = -1, name: string = '', err?: Error | string) {
        super()
        this.name = name
        this.code = code 
        if(err) {
            // no type guards
            this.message = this.name + ": " + (err instanceof Error)? err.message : err
        } else {
            this.message = this.name
        }
    }
}

export class MyError3 extends Error {
    public code; name; message

    constructor(code: number = -1, name: string = '', err?: Error | string) {
        super()
        this.name = name
        this.code = code 
        // type guards... but at what cost to brevity
        this.message = this.name
        if(err) {
            if(err instanceof Error) {
                this.message += ": " + err.message
            } else {
                this.message += ": " + err
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

TypeScript可以正确处理三元语句中使用的类型保护。您对括号的使用导致了与您在这些语句中所期望的不同的行为。如果您在前两个示例中格式化代码,那么一切都应该正常工作:

export class MyError extends Error {
    public code; name; message

    constructor(code: number = -1, name: string = '', err?: Error | String) {
        super()
        this.name = name
        this.code = code 
        this.message = this.name + (err ? ": " + (err instanceof Error ? err.message : err) : '')
    }
}

export class MyError2 extends Error {
    public code; name; message

    constructor(code: number = -1, name: string = '', err?: Error | String) {
        super()
        this.name = name
        this.code = code 
        if(err) {
            this.message = this.name + ": " + (err instanceof Error ? err.message : err)
        } else {
            this.message = this.name
        }
    }
}

我还认为围绕括号中的整个三元语句有助于使其更具可读性,但这当然是个人观点的问题。

那么你的三元陈述有什么不对?由于operator precedence rules,第一个?左边的所有内容都是同一个表达式的一部分,因此所有内容都连接在一起,这改变了三元组的整个含义。这是一个例子:

this.message = this.name + ": " + (err instanceof Error)? err.message : err
// same as: 
(this.name + ": " + (err instanceof Error)) ? err.message : err
// with values filled in:
"someName: true" ? err.message : err

因此,上述代码将始终评估err.message err是否为Error