学习TS居然是因为上班摸鱼太无聊了(一)

前言

又有两个星期没有写文章了,自从上次拿到了字节的oc之后就开启了我的摆烂生活,现在已经上班两个星期了,先说说感受吧,用我身边其他大厂的朋友总结的七个字就是---------又舒服了,字节哥。不得不说,字节在员工福利这一块真没得说,免费的三餐和下午茶、免费的健身房和住房补贴以及晚上加班到九点半之后的打车报销,虽然杭州这边工区的伙食不是很好,但我还是想说,在字节上班我都要吃胖了,无奈之下只能去健身房收收肚子。

为什么要学TS

两个原因,一呢是因为公司的项目都是ts,不学一下很多代码都看不懂。第二个就是因为实在是太无聊了,实习生刚来没啥事,就分了一个需求给我,然后就是琢磨一下mac,毕竟之前没用过,剩下的时间就是新人培训的刷课和熟悉项目代码,光看代码看得我都要睡着了,所以还是找点事干,就学了一下ts,又能学习又有工资,何乐而不为呢。

常用类型

ts相较于js来说,最显著的地方应该就是类型定义了,这种类型定义的语法和spark有点像,所以我上手起来没那么困难。这篇文章主要分享一些ts里的常用类型,因为其他的知识点我也还没看,摸鱼嘛,肯定还是以摸为主,学为辅,哈哈哈。

基本类型

在ts中,有三种常见的基本类型,就是number、string、boolean。这三种类型在js中已经快见吐了,直接上语法吧。

ts 复制代码
let n3: number; 
function add(number1: number, number2: number) { 
    return number1 + number2 
}
var s4: string;
s4 = 'abc'
let b3: boolean = true;

这里我就不多解释了,语法嘛,硬记就是了,ts完美的兼容了js的语法,所以js的那种写法我就不列举了。

哦,忘记了,ts和js还有一个不一样的地方就是ts会在编译时就找出你的语法错误,而js是在运行时检查,啥叫编译时找错呢,参考一下其他后端语言就知道了,比如C语言,毕竟C语言是所有语言他娘。

数组

数组的声明方法有两种,第一种是常规写法,第二种是泛型,啥是泛型呢,后面再说。ts还新增了一个readonly关键字,表示只读,用readonly声明的数组都是只读数组,只读数组的声明方法也有两种。数组还支持放多种类型的元素,这种类型叫做联合类型,后面会提到。

ts 复制代码
const arr1: number[] = []; 
const arr2: string[] = []; 
const arr3: boolean[] = [];

// 泛型声明
const arr1: Array<number> = [];
const arr2: Array<string> = []; 
const arr3: Array<boolean> = [];

// 只读数组
const arr1: readonly string[] = []; 
const arr2: ReadonlyArray<string> = [];

// 联合类型的数组
const arr1: (number | string)[] = [];
const arr2: Array<number | string> = [];

枚举(enum)

枚举也是ts独有的数据类型,它和js中的对象有点像,不过也就是有点。枚举有以下类型:数字枚举字符串枚举异构枚举

  • 数字枚举
    如果没有显式赋值的话,也是枚举的默认赋值行为。枚举的每一项的值都是前一项被赋值的值加1。第一项枚举值是0。
ts 复制代码
enum Fruit { 
    apple, // 0 
    orange, // 1 
    banana, // 2 
} 
enum Fruit { 
    apple = 1, // 1 
    orange, // 2 
    banana = 100, // 100 
    watermelon, // 101 
}

// 枚举的值支持动态计算,但动态计算的枚举值下一项必须赋值。
enum Fruit { 
    apple = getDefaultFruit(), 
    orange = 1, // 需要赋值 
}
  • 字符串枚举
    字符串枚举的每一项的值都是基本类型string或者另一个字符串枚举的成员,并且枚举不支持动态计算枚举值
ts 复制代码
enum Direction { 
    up = 'up', 
    down = 'down', 
    left = 'left', 
    right = 'right' 
} 
enum Direction_up { 
    up = Direction.up,
    down = getDefault(), // TS Error.含字符串值成员的枚举中不允许使用计算值。
}
  • 异构枚举
    异构枚举是一种成员既有数字也有字符串成员的枚举类型,每一项字符串成员后定义的成员必须赋初始值,并且不支持动态赋值
ts 复制代码
enum Fruit { 
    apple, 
    orange = 'orange', 
    banana = 1, 
    watermelon = get(), // TS Error.含字符串值成员的枚举中不允许使用计算值
}

联合类型(union)

联合类型意味着多种类型合并在一起所产生的一种类型。使用"|"符号来将多种类型组合,给这种类型赋值时,也只能选择其中一种类型的值。在不能确认具体是哪一种类型的情况下,只能访问其所有类型共有的特性,只有显示赋值之后才能访问其独有的方法。

ts 复制代码
let message: string | number | boolean = 0; 
message = 'ok'; 
message = false;

// 未显示赋值
function run(message: string | number) { 
    message.toFixed(); // TS Error.类型"string"上不存在属性"toFixed" 
}

// 显示赋值后
let message: string | number; 
message = '' 
message.length; 
message = 1; 
message.toFixed();

元组(tuple)

元组类型是一种特殊类型的数组。

  • 简单元组
    声明时就知道数组里有多少元素,每个元素的类型是什么。简单元组类型的长度是固定的。修改每个位置的值时,不能赋与对应位置值的类型不相同的值。
ts 复制代码
const t1: [string, number] = ['1', 2]; 
const t2: [number[], readonly number[]] = [[], []]; 
t1[0] = '' 
t2[0] = t2[1]; // TS Error.类型 "readonly number[]" 为 "readonly",不能分配给可变类型 "number[]"。
  • 可选元祖
    可以利用optional符号"?"来指定元组中的某一项是否是可选的。只有元组的最后一项可以是可选的元素。可选元组的长度不是固定的,会根据可选元素的数量动态变化。
ts 复制代码
function OptionalTuple1(tuple: [string, number?]) { 
    tuple.length; // length: 1 | 2 
} 
function OptionalTuple2(tuple: [string, number, boolean?]) { 
    tuple.length; // length: 2 | 3 
}
  • 具名元组
    元组的每个值定义了其类型,但使用者并不知道每个值代表什么含义,为了解决这个问题,TypeScript4.0引入了具名元组。支持类似于对象类型的方法给元组每个值都赋予一个名字。
ts 复制代码
let person: [name: string, age: number];

函数

在ts中函数类型可以有多种定义方式,除了接口函数外每种定义方式都映射了JavaScript中定义函数的方式。其中箭头函数是ES6的新特性,但在TypeScript中,它表示一个函数类型,即任何类型的函数都能赋值给箭头函数类型的值。

ts 复制代码
// 使用接口声明数类型 
interface Hello { (): void; } 

// 使用type声明箭头函数类型 
type Hello = () => void; 

// 使用function关键字声明函数类型 
function Hello(): void; 
const func1: () => number = () => { return 0; }; 
const func2: () => number = function () { return 1; };

函数最关注的其实就是两个点,一个是参数,另一个是返回值,ts中还有函数重载

参数常见的有一般参数可选参数默认参数

ts 复制代码
function F1(var1: number, var2: string) {} 
const F2 = function (var1: number, var2: string) {};

// 可选参数
function F1(var1: number, var2?: string): any; 
const F2 = function (var1: number, var2?: string) {};

// 默认参数
function F1(val = '') {} 
const F2 = function(var1 = 2) {}

返回值类型通常在参数列表之后定义。与变量类型类似,我们通常不需要返回类型注释,因为 TypeScript 会根据函数的return语句推断函数的返回类型。函数类型有3种定义方式,每种方式都有注明返回值类型的方式

ts 复制代码
function F1(): number; 
interface F2 { 
    (): string; 
} 
type F3 = () => boolean;

函数的名称相同,但是函数的参数类型或者个数不同,就是函数的重载。但需要注意的一点是,TypeScript的函数重载是声明式的重载,是方便使用者调用时候查看在不同情况下应该怎么传参。由于JavaScript并不支持重载,所以真正的函数实现时仍然需要根据不同的参数类型,在代码中写入很多分支逻辑,这是不可避免的。

ts 复制代码
function greet(name: string): string; 
function greet(name: string[]): number; 
function greet(val: string | string[]): string | number { 
    if (typeof val === 'string') return val; 
    return val.length; 
}

对象、interface、type和特殊类型

  • 对象
    对象类型描述了一个具体的JavaScript对象,包含了所有键值对的描述。其实和js差不多,只是多了类型的声明而已。
ts 复制代码
const object: { a: number, b: string; c: boolean, } = { a: 1, b: '1', c: true }

// 如果不指定属性的值类型,TypeScript默认为any类型,但不推荐这么做。
const object: { 
    a, // any  
    b, // any 
    c, // any 
} = { a: 1, b: 1, c: {} }
  • interface(接口)
    有过java基础的人对这个应该不陌生,因为java里也有接口的定义,接口是声明对象类型的一种方式,接口提供了对象类型的一种命名宏,不能声明基本类型。在接口声明的上下文中可以直接使用该类型赋值给多个对象声明,节省了给每个对象写字面量对象类型的时间。
ts 复制代码
interface Animal { 
    name: string; 
    age: number; 
    canEat: boolean; 
} 
const dog: Animal = { name: 'dog', age: 1, canEat: false };
const chicken: Animal = { name: 'chicken', age: 2, canEat: true };

// interface也可以定义函数类型,也可以给函数定义其他额外属性
interface Plus { 
    (init: number): number; 
    revoke: (init: number) => number; 
} 
const plus: Plus = (init: number) => { return init + 1; }; 
plus.revoke = (init: number) => init - 1; 
let result = 1; 
result = plus(result); 
result = plus.revoke(result);
  • type
    type本质是给一系列类型起一个别名,类似于用interface关键字给对象类型命名。type和interface在使用上有一些区别,使用type声明类型别名时,需要用"="符号把相应的类型"赋值"给类型别名。
ts 复制代码
type Point = { x: number; y: number; }
function draw(point: Point) {}
type UserInputValue = string; 
type InputValid1 = (input: UserInputValue) => UserInputValue;

// 声明的别名类型是可以换的,如果UserInputValue想换成number,直接换就可以了
type UserInputValue = number; 
  • 特殊类型
    特殊类型常见的有anyunkonwnnevervoid,这里就介绍一下any和never,因为unknown我也没搞懂,我怕误导你们,所以等我搞懂再说,void很好理解,就是函数没有返回值,用来声明空函数。
ts 复制代码
// any类型的含义是这个值可以是任何其他类型,你可以在any类型的值上进行任何操作
let val: any = 1; 
val = '2'; 
val = () => {} 
function main(number1) { // function main(number1: any): any 
    return number1; 
}

// never表示从未观察到的值,或者通过ts类型推断不出来的值,never类型只能赋值给never类型
enum Fruit { apple, orange, } 
function checkOverdue(fruit: Fruit) { 
    if (fruit === Fruit.apple) { } 
    else if (fruit === Fruit.orange) { } 
    else { fruit; // fruit: never 
}

// never是任何类型的子类型,extends是js的es6新增的关键字,表示继承
type N1 = never extends string ? true : false; // type 
N1 = true; type N2 = never extends number ? true : false; // type 
N2 = true; type N3 = never extends boolean ? true : false; // type N3 = true;

结语

好久没写文章了,手有点生了,这篇文章虽然内容比较简单,但是却写了好久,金三银四已经过去了,现在已经进入铜五了,近期应该有很多春招补录,最近boss上收到了几个阿里的私信叫我丢简历,如果不是kpi的话应该就是真缺人,所以应该还是有很多岗位的,大家都加油吧

相关推荐
正小安1 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch3 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光3 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   3 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   3 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web3 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常3 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇4 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr4 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho5 小时前
【TypeScript】知识点梳理(三)
前端·typescript