将联合类型与包装对象检查一起使用

时间:2019-04-03 17:45:30

标签: typescript

我正在尝试将联合类型与简单的原语和一些自定义对象一起使用。例如,我在“联合类型”部分的docs中演示了示例联合类型,并添加了一个人为的PaddingLeft类型,如下所示:

type PaddingLeft = {
  aNumber: string,
}

function padLeft(value: string, padding: string | number | PaddingLeft) {
  if (typeof padding === "object") {
    return padding.aNumber + value;
  }
  if (typeof padding === "number") {
    return Array(padding + 1).join(" ") + value;
  }
  if (typeof padding === "string") {
      return padding + value;
  }
  throw new Error(`Expected string or number, got '${padding}'.`);
}

并这样称呼它:

padLeft('1', 1);
padLeft('1', '2');
padLeft('1', {aNumber: '34'});

基于上述padLeft的实现,Typescript很高兴。但是,我真的不想写:

if (typeof padding === "object") {

,而是包装对提供的参数是否为函数内对象的检查,因此除简单的typeof检查外,我还可以进行其他检查。首先,我尝试编写一个与typeof检查功能相同的函数,但在函数内部:

function isObjectCheck (args: any) {
  return (typeof args === 'object');
}

然后我尝试用对isObjectCheck的调用替换typeof检查(替换padLeft函数的第一行):

if (isObjectCheck(padding)) {

这样做会使Typescript说:

  

类型'string |中不存在属性'aNumber'编号PaddingLeft'。     属性“ aNumber”在类型“字符串”上不存在。

在padLeft函数的第二行。

如何将对象检查包装到函数中,并同时满足Typescript的检查?

1 个答案:

答案 0 :(得分:1)

您正在寻找自定义类型的防护装置。这将起作用:

type PaddingLeft = {
    aNumber: string,
}

function isObjectCheck(args: any): args is object {
    return (typeof args === 'object');
}

function padLeft(value: string, padding: string | number | PaddingLeft) {
    if (isObjectCheck(padding)) {
        return padding.aNumber + value;
    }
    if (typeof padding === "number") {
        return Array(padding + 1).join(" ") + value;
    }
    if (typeof padding === "string") {
        return padding + value;
    }
    throw new Error(`Expected string or number, got '${padding}'.`);
}