Skip to content

类型

在 TS 中我们可以将一个属性的类型定义为中多种类型,特别是对于对象子属性存在不同类型的时候经常容易出错,其中主要有以下几种方式:

  1. in
  2. typeof
  3. instranceof
  4. is 类型保护函数

对象类型中 ?: 属性 访问问题

js
interface Config {
  name: string;
  age?: number;
  address?: string | string[];
}

如上面的 config 类型 当我们如下面去处理 age 的时候

js
// 如果没有定义 age 那么默认设置为 18岁, 如果定义了岁数,那么需要加一变成 虚岁
const getAge = (config: Config): number => {
  if (config.age !== undefined) {
    // 这时候发现会出现报错
    return config.age + 1
  }
}

image-20210219153817945

那么这时候怎么处理?

  1. 使用 as 或者 <number>鸭子类型进行处理
js
const getAge = (config : Config) : number => {
    if(config.age !== undefined){
        // 这时候发现会出现报错
        return (config.age as number) + 1
    }
}

不确定入参个数

在 ajax 中 我们对于接口的请求支持多种方式

  • $.get('/xxx/xxx' , { a : 1 })
  • $.get({ url : '/xxx/xxx' , params: { a : 1 } }) 那么这种类型如何处理
js
const uncertainInputParameters = (url: string | AjaxOptions, option?: AjaxOptions): AjaxOptions => {
  let options: AjaxOptions
  // 如果支持不同个数的入参 去分别处理并统一变成 options
  if (typeof url === "string") {
    options = Object.assign({}, option || {}, {
      url: url,
    })
  } else {
    options = Object.assign({}, url)
  }
  return options
}

如果是三个 如我们自定义 http 请求的时候 需要支持一下三种格式

  • http.get(url , params , options )

  • http.get(url , params )

  • http.get(options )

这时候怎么处理?

js
const uncertainInputThreeParameters = (
  url: string | AjaxOptions,
  params ?: any,
  option?: AjaxOptions
): AjaxOptions => {
  let options: AjaxOptions;
  // 如果支持不同个数的入参 去分别处理并统一变成 options
  if (typeof url === "string" && option !== undefined) {
    options = Object.assign({}, option || {}, {
      url: url,
      params : params
    });
  }else if (typeof url === "string" && option === undefined) {
    options = Object.assign({}, {}, {
      url: url,
      params : params
    });
  }else{
    options = url as AjaxOptions;
  }
  return options;
};
  1. 最好的办法还是借助于 ...
js
const uncertainInputParameters = (...args): AjaxOptions => {
  let options: AjaxOptions
  // 如果支持不同个数的入参 去分别处理并统一变成 options
  if (args.length === 1) {
    options = Object.assign({}, args[1])
  } else {
    options = Object.assign({}, args[1], {
      url: args[1],
    })
  }

  return options
}

总结

可以看出在 TS 中对于我们不确定类型的时候我们需要经常借助于 as ,<类型>去确定属性的类型,但是在.tsx文件中我们因为 jsx 语法问题导致 <xxx>于元素节点冲突,所以我们最好是 as的鸭子类型处理