类型约束 和 编译结果对比

TS是一个可选的静态的类型系统 编译成js之后,就啥都不管啦

如何进行类型约束

有了约束后,才能进行类型检查。一般要对 变量、函数的参数&返回值等 的后面加上 :类型
类型约束后,不可修改变量类型!

  1. TS在很多场景中可以完成类型推导
  2. 若用F2,修改变量名字,则自动更改这个变量所有位置的名字
  3. F12可以跳到函数定义的地方
  4. let anyVar;//这个anyVar是any类型,可以再次多次被赋值为任意类型,因为TS不会对any进行类型检查
  5. 小技巧:如何区分 数字字符串和数字?关键看怎么读
    1. 数字读法就是 xx亿xx千万百万。。

      源代码和编译结果的差异

      ts源代码就只是比编译结果多了个类型约束和类型检查

基本类型

  • number: 数字
  • string: 字符串
  • boolean: 布尔
  • 数组:
    • let nums: []; //不报错,但是代表它永远只能取值为一个空数组,里面就是never类型!
    • let nums: number[]; //每一项都是数字的数组,它实际是下述写法的语法糖,推荐这么写
    • let nums: Array = [3, 4, 5]; //这是完整写法但是,这么写容易跟组件搞混了
  • 对象:
    • let obj: object; //这个约束并不强,不精准
  • null 和 undefined:
    • null和undefined是所有其他类型的子类型,它们可以赋值给其他类型!
    • 例如:let n:string = undefined; //可以,但是会有隐患啊,那怎么办呢
      • 在compilerOptions中配置 “strictNullChecks”: true, 可以获得更严格的空类型检查,这样null和undefined的变量就不能赋值为其他类型了

        其他类型

  1. 联合类型:多种类型任选其一,配合类型保护进行判断
    1. let name: string | undefined; //string或者undefined
    2. 类型保护:当对某个变量进行类型判断(typeof可以触发普通基本类型保护,对象不行)之后,在判断的语句话中便可以确定它的确切类型
  2. void类型:通常用于约束函数的返回值,表示该函数没有任何返回值,这不是undefined
  3. never类型:通常用于约束函数的返回值,表示该函数永远不会结束
    1. 常用于抛出错误函数的返回值
    2. 死循环函数
  4. 字面量类型:使用一个值进行约束,强力的约束,浅层对比约束一般不使用这种方式

    1. let ccc: {name: string, obj:object};
    2. ccc = {name:'324', obj:{ok: 'ok'}};
    3. console.log(ccc);//{ name: '324', obj: { ok: 'ok' } }
    4. ccc.name = '4252';
    5. ccc.obj = {ok: 324}
    6. console.log(ccc);//{ name: '4252', obj: { ok: 324 } }
  5. 元组(Tuple)类型:一个固定长度的数组,数组中每一项的类型也确定

    1. let tu: [string, number] = [“3”, 4];
  6. any类型:any类型可以绕过类型检查,因此,any类型的数据可以赋值给任意类型,故也会造成隐患

类型别名

就是为了解决这种重复代码的问题:
image.png
类型别名:使用type ,对已知的一些类型定义名称,而且还可以进行组合嵌套!
注意,它不会出现在编译结果中,尴尬!

  1. type Gender = '男' | '女';
  2. type User = {
  3. name: string//这里不管是用逗号 分号 还是不写,都不报错,无语..
  4. age: number
  5. gender: Gender
  6. }
  7. let u:User;
  8. u = {
  9. name: "wujingwei",
  10. gender: "男",
  11. age: 22
  12. }
  13. function getUsers(g: Gender):User[]{
  14. return [];
  15. }
  16. getUsers('男');

函数的相关约束

  1. 函数重载:在函数定义之前,对函数调用的多种情况进行声明 ```typescript function combine(a:number, b:number):number;//得到a*b的结果 function combine(a:string, b:string):string;//得到a与b拼接的结果

function combine(a: number | string, b: number | string): number | string{ if(typeof a === ‘number’ && typeof b === ‘number’){ return a * b; }else if(typeof a === ‘string’ && typeof b === ‘string’){ return a + b; }else{ throw new Error(‘a和b必须是相同的类型,且是number或string’); } }

const result = combine(3, 4); combine(3, “3”);//这样这句在静态的时候,编译器就会在这里报红色error了,通不过编译

  1. 2. 可选参数:可以在某些参数名后面加上 **问号?**,表示可选可不选,即 ?:
  2. 1. **可选参数必须出现在参数列表的最后一个! **
  3. <br />
  4. <a name="xF8RG"></a>
  5. # 扑克牌小练习
  6. 1. 目标:创建一副扑克牌(不包括大小王),打印该扑克牌
  7. ```typescript
  8. //一副牌
  9. type Deck = NormalCard[];
  10. //花色
  11. type Color = '♥️'|'♠️'|'♦️'|'♣️';
  12. //一张牌
  13. type NormalCard = {
  14. // color: string,//花色, 进行一下限制, 因为总共就四种
  15. color: Color,
  16. mark: number,//序号
  17. };
  18. function createDeck(): Deck {
  19. const deck: Deck = [];
  20. for (let i = 1; i <= 13; i++) {
  21. deck.push({
  22. mark: i,
  23. color: '♥️',
  24. });
  25. deck.push({
  26. mark: i,
  27. color: '♠️',
  28. });
  29. deck.push({
  30. mark: i,
  31. color: '♦️',
  32. });
  33. deck.push({
  34. mark: i,
  35. color: '♣️',
  36. });
  37. }
  38. return deck;
  39. }
  40. function printDeck(deck: Deck): void{
  41. const len = deck.length;
  42. for (let i = 0; i < len; i++) {
  43. const card = deck[i];
  44. let str = card.color;
  45. if(card.mark <= 10){
  46. str += ' '+card.mark;
  47. }else if(card.mark === 11){
  48. str += ' J';
  49. }
  50. else if(card.mark === 12){
  51. str += ' Q';
  52. }else if(card.mark === 13){
  53. str += ' K';
  54. }
  55. console.log(str);
  56. }
  57. }
  58. const deck = createDeck();
  59. printDeck(deck);

感觉就是,好智能啊,很多提示!!