不要在对象文字中扩展潜在的文字类型

时间:2018-03-22 15:55:44

标签: typescript type-inference

我经常使用由字符串和数字组成的不可变对象。例如:

const InternalServerError = {
    status: 500,
    message: 'Internal Server Error'
}

我从不更改属性,因此我希望InternalServerError的类型使用数字和字符串文字,如下所示:

{
    status: 500,
    message: 'Internal Server Error'
}

但是,TypeScript会自动扩展推断类型InternalServerError

中的类型
{
    status: number,
    message: string
}

我可以将每个属性转换为其文字类型,如下所示:

const InternalServerError = {
    status: 500 as 500,
    message: 'Internal Server Error' as 'Internal Server Error'
}

但这有两个问题:

  1. 重复,特别是对于长字符串
  2. 可以将值强制转换为错误的文字类型(例如500 as 501),并且编译器不会抱怨,这样就容易产生拼写错误。
  3. 最简单的(最少样板代码或重复)和大多数类型安全(未捕获类型错误的可能性最小)方法是什么?

1 个答案:

答案 0 :(得分:0)

您可以使用泛型创建辅助函数来推断精确类型(例如500而不是number):

function makeError<
    S extends number,
    M extends string
>(status: S, message: M): {status: S, message: M} {
    return {status, message}
}

const InternalServerError = makeError(500, 'Internal Server Error')
const NotFoundError = makeError(404, 'Not found')

// Code = 500
type Code = (typeof InternalServerError)['status']
// Message = Internal Server Error
type Message = (typeof InternalServerError)['message']