[译]<<Effective TypeScript>> 技巧39:选择更精准的any变体

195 阅读1分钟

本文的翻译于<<Effective TypeScript>>, 特别感谢!! ps: 本文会用简洁, 易懂的语言描述原书的所有要点. 如果能看懂这文章,将节省许多阅读时间. 如果看不懂,务必给我留言, 我回去修改.

技巧39:选择更精准的any变体

any表示集合非常庞大,当我们使用any时,需要想想有没有更精准的any变体:

function getLengthBad(array: any) {  // Don't do this!
  return array.length;
}

function getLength(array: any[]) {
  return array.length;
}

上面的第二种方法的好处:

  • 会对用到array.length会进行类型检查
  • 函数的返回值类型会推断为number,而不是any
  • 调用getLength会自动检查参数是否是array:
    getLengthBad(/123/);  // No error, returns undefined
    getLength(/123/);
           // ~~~~~ Argument of type 'RegExp' is not assignable
           //       to parameter of type 'any[]'
    

如果你期待某类object,但是不知道其中的值,可以用:{[key: string]: any}:

function hasTwelveLetterKey(o: {[key: string]: any}) {
  for (const key in o) {
    if (key.length === 12) {
      return true;
    }
  }
  return false;
}

这里也可以 object 类型,但是有点不一样,object可以获取key,但是不能获取value:

function hasTwelveLetterKey(o: object) {
  for (const key in o) {
    if (key.length === 12) {
      console.log(key, o[key]);
                   //  ~~~~~~ Element implicitly has an 'any' type
                   //         because type '{}' has no index signature
      return true;
    }
  }
  return false;
}

如果你期待函数,也有几种any函数变体可以选择:

type Fn0 = () => any;  // any function callable with no params
type Fn1 = (arg: any) => any;  // With one param
type FnN = (...args: any[]) => any;  // With any number of params
                                     // same as "Function" type

值得注意的是:...args要标注类型:any[]而不是 any

const numArgsBad = (...args: any) => args.length; // Returns any
const numArgsGood = (...args: any[]) => args.length;  // Returns number

any[]的使用真的很常见。