2TypeScript中的数据类型上

80 阅读5分钟

一. JS/TS中有哪一些数据类型(data type)

  • js目前的数据类型有八种
  null undefined string number 
  boolean bigint symbol object
  • 可以通过2321分组去记,两个空这一点是js编程语言的特色,其实也可以说是设计缺陷其它语言都是一个空。3个常用的数据类型,string number boolean,接下来bigint 和 symbol放一组,实际开发中也用的不多。最后就是object对象,可以包含Array,Function,Date...,所有复杂一点的对象。
  • ts的数据类型,以上所有另外包含 void, never, enum, unknown, any
  • 再加上两个s自定义类型type和interface,其实也就是三类,第一类是js中有的,第二类是五个自己有的类型,第三类就是自定义类型

二. 如何理解TS的数据类型

  • 在js中我们认为的数据类型通常是某个值,而在ts我们应该从集合的角度去理解ts中的类型,举个例子,在js中

      let a = 1
    
  • 我们认为a是一个数字,而在ts中let a: number = 1, 我们认为其中的number这个数字类型代表所有数字的集合,它可以是1|2|-1|1.1|2.2等等所有数字。

三. number和Number,string 和 String, boolean 和 Boolean的区别。

  • 拿number去举例,即let a = 1let a = new Number(1)的区别,

    • 区别就是前一种是存粹的0101在内存中表示一个数字,后一种是一个对象它会有toFixed,valueOf等等方法,只有valueOf的时候才返回真正的值。我们通常也不会去用后面的写法,只有在直接使用1.toFixed()这样的方法时候js会暗箱操作,先let temp = new Number(1),再去把temp.toFix()的值返回,然后删除temp,你可以理解成这是js偷偷摸摸帮你完成了这些操作。
  • TS中的Object包含有Number,String和Boolean类型,既然js中我们不用ts中我们也不用,我们也不用大写的Object因为范围太大。

四. 如何在TS里面描述对象的data type

  • 用class/constructor描述,这种方式比较死板
  const aFunction = () => console.log(1)
  • 用type或者interface描述,推荐这种方式,因为灵活
  type Person: {
    namestring
    agenumber
  }
  const a:Person = {
    name'caikun',
    age18
  }
  // 另一种写法,叫做索引签名来描述对象,表示A这个类型是一个对象,它的key必须是string,值必须是value,其中k可以随便写
  type A = {
    [kstring] : number
  }
  // 还有一种写法,叫做Record泛型来描述对象和上面写法的含义是一摸一样的
  type A2 = Record<stringnumber>

五. 描述数组对象

type A = string[]
// 等价于
type A = Array<string>
// ts中的远足的写法,下面这种是三元组,面试喜欢问。
type B = [stringstringstring]
const error: B = ['A''B'// 会报错,少了一个元素,是一个二元组
// 还可以数组包含数组
  • 总结: ts中一般用Array<?>或者string[]或者[string, number]来描述数组

六. 描述函数对象

// 这里先讲一下最基本的写法,详细写法之后会具体再研究
type FnA = (a: number, b: number) => number;
const aFnA = () => {
  return 123// 这样没参数也没报错,ts函数的类型检查,对于函数参数来说是松散的,参数少了可以,但是多了会报错
};
// 如果没有返回值,需要用void来表示
type FnReturnVoid = () => void;
const f1FnReturnVoid = () => {
  console.log('hi');
};
// 以上都是写的箭头函数没有this,下面是支持this的例子

type Person = {
  namestring;
  agenumber;
  sayHiFnWithThis;
};
type FnWithThis = (this: Person, name: string) => void;
const sayHiFnWithThis = function () {
  console.log('hi ' + this.name);
};

const xPerson = {
  name'张三',
  age18,
  sayHi: sayHi,
}; 
x.sayHi('Jack'); // hi 张三
// 等价于
sayHi.call(x, 'Jack')
// 如果你的函数有this,第一点,调用的时候必须显式的传递这个this,第二点,一般而言不能用箭头函数用function。第三点,后面的参数按照除了this之后的开始匹配。
  • 总结: Function太不精确,一般用()=> ?来描述函数

六. 描述其它对象

const dDate = new Date();
const rRegExp = /ab+c/;
const r2RegExp = new RegExp('ab+c');
const mMap<stringnumber> = new Map();
m.set('xxx'2);
const wmWeakMap<{ namestring }, number> = new WeakMap();
console.log(wm);
const sSet<number> = new Set();
s.add(123);
const wsWeakSet<string[]> = new WeakSet();
console.log(ws);
  • 总结: 其它对象一般直接用class描述,另外其实这里包含了类型推测的概念,Date,RegExp都可以直接删除,但是Map不行,只要删除之后类型不损失就可以删除。

七. any、unknown是什么?

  • 从集合的角度理解,any就是把所有类型并进来
  • unknown,就是一个集合,里面是什么不知道,比any好,有机会断言,相当于一个盖住类型的集合,尽量使用unknown
const a: unknown = 1;
console.log(a);
a.toFixed(); // 这样不行。
const b = (a as number).toFixed; // 这样可以,适合这个值是从外部获取的场景,as number相当于就是把盖子揭开

八. never是什么

  • never就是空集,不包含任何元素
  • 使用场景,用来做检查
type C = string & number;

// const Cake: C = 'ab'; // 会报错误,这个Cake就是never类型,没办法使用,也没人这么用,看得出never就不是给人声明用的

type A = string | number | boolean;

const a: A = 'hello' as any; // 这样写是为了假设不知道a是什么类型
if (typeof a === 'string') {
  a.split('');
} else if (typeof a === 'number') {
  a.toFixed(2);
} else if (typeof a === 'boolean') {
  a.valueOf();
} else {
  a.toFixed(); // 会报错,这里的a就是never类型
  console.log('没了');
}