学习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的话应该就是真缺人,所以应该还是有很多岗位的,大家都加油吧

相关推荐
桂月二二31 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者4 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794484 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存