本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
本系列旨在帮你用正确的方式打开TypeScript。
前言
TypeScript,是JavaScript的超集...每次看到TypeScript教程的时候,文章都会从它的背景,一直介绍相比JavaScript的种种好处,然后再抛出一大堆的TypeScript知识要点。
可到了最后,真正上手的时候,却又好像只学会了let name:string
。而文章所述的知识点,其实在TypeScript 中文手册 中都可以找到,而且更加全面。
所以,相对于知识点的广撒网,不如来学习一下,TypeScript在实战中该怎么用,在什么时候用。
更实用的TypeScript指南系列,从不同的使用场景出发,学习不同的TS语法点。让你不仅了解TS,更会用TS🧐。
系列文章
更实用的TypeScript指南:不墨迹的入门 - 掘金 (juejin.cn)
更实用的TypeScript指南:从ES6的class到TS的装饰器 - 掘金 (juejin.cn)
一个故事带你了解TypeScript程序类型 - 掘金 (juejin.cn)
不墨迹的知识点简介
下文将会用尽量简短的篇幅,概括常用的知识点并给出使用样例(默认你是对TypeScript有大概的概念的)。
如果想进一步了解,每个标题都链接了官方网站的地址。
基础类型
boolean //布尔
number //数字
string //字符串
object //对象
number[] string[] 等 数据类型[] 或 Array<number> Array<string> 等 Array<数据类型> //数组
any[] //不确定个数,不确定类型的数组,但是不好的地方是就没有实时的编译提示了
any //任何类型
unknown //任何类型的安全形式
undefined null
//默认情况下null和undefined是所有类型的子类型,但是如果想把其赋值给某个类型的变量,想要不报错首先要关闭严格模式
void //没有类型,如 function f:void () { ... } 无返回值
never //函数无法返回的类型。
//例如一个会抛出异常的函数 就可以写 function f(msg:string):never {throw new Error(msg)}
enum //枚举
例:
enum Color {Red = 2, Green, Blue}
let c: Color = Color.Green;
let d:string = Color[2]
console.log(c)
>> 3
console.log(d)
>> Red
let a:[string,number,boolean] = ['xxx',12,true]
//元组 与数组不同的是可以存在不同类型,但是数据类型的位置和个数要一一对应
类型一|类型二 //联合类型,同时接受多种类型
(<string>str).length 或 (str as string).length //类型断言,断言某个变量是某种类型,以防止报错。
//这个为例,断言str是string类型,所以在提前不知道str的类型的情况下,使用.length方法也不会报错
需要注意的是很多地方没有提到的unknow
类型,他与any不同的是使用unknown可以保证类型安全,而any则直接不进行类型检查,相当于又回到了JavaScript🤣,所以我们可以在很多情况下都用unknown来代替any。
例如:
let b:unknown //当我们不知道类型的时候,先用unknown类型
b = 'abc'
let l:number = (b as string).length //某种情况下,我们确定了类型则使用类型断言来确定类型
//如果不用类型断言则会出现错误,而一开始换成any则不会,这是unknown安全性的体现
更多内容可以参考 [译] 理解TypeScript 中 any 和 unknown
接口(interface)
你可以把接口理解为一个契约,遵守契约的类型都有必须根据接口做出规范。
基本用法(含常见点)
interface Iperson {
readonly firstName: string //只读
lastName: string
sex?: string //?:表示可以没有
}
function showFullName(person: Iperson) {
return person.firstName + person.lastName // person.qq是没有的
}//这里的函数传入的参数,必须同时具备firstName,lastName两种属性,但是多具备其他属性则不做要求,在传进时会把多余的参数去掉
let q: object = {
firstName:'xx',
lastName:'x',
qq:'123'
}
console.log(showFullName(q as Iperson)) //注意这里断言了q是Iperson型,不然会类型不一致
>> xxx
接口也可以是函数类型的接口
//定义一个函数的规范
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function(so: string, su: string) {
let result = so.search(su);
return result > -1;
}
同时接口可以定义类类型
(没用过类的直接跳到 更实用的TypeScript指南:从ES6的class到TS的装饰器 ,让你知道一些类的简单用法)
//定义两个接口
interface Time {
currentTime: Date;
setTime(d: Date): void;
}
interface Name {
name: string;
setname(pname: string): void;
}
//类使用接口
class Clock implements Time, Name {
name:string
currentTime: Date
other: string //可以在类中多定义属性,只要包含所有接口特性就行
setTime(d: Date) {
this.currentTime = d;
}
setname(pname: string) {
this.name = pname;
}
constructor(h?: number, m?: number) { } //构造函数类是接口不约束的
}
接口也可以继承:
interface L {
len: number;
}
interface S extends L {
area: number;
}
let s = <S>{}; //注意这里使用是断言,也可以写成let s: S = ({} as S)。和泛型区分开
s.len = 10, s.area = 100
其他用法,我们遇到具体场景具体说明,这里如果一股脑排列出来反而会混乱。
类(class)
这里你只介绍类是什么和基本知识点,为了是先看懂,他的应用将在 更实用的TypeScript指南:从ES6的class到TS的装饰器 中根据具体使用场景说明。
class Animal {
private name: string = 'daHuang';//私有
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
//继承
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
>> Woof! Woof!
dog.move(10);
>> Animal moved 10m.
dog.name //报错:属性“name”为私有属性,只能在类“Animal”中访问。
函数(function)
函数声明
const add = function(x:number = 1,y?:number):number {
if(y)
return x+y
else
return x
}
//add函数参数必须是数字类型,返回值必须是数字类型,x默认是1,y可选
函数重载
根据传入不同的参数而返回不同的类型
function add(x:string,y:string):string
function add(x:number,y:number):number
function add(x,y) {
if(typeof(x) === 'string')
return 'the String'+x+y //字符串拼接
else return x+y //相加
}
add(1,2)//可以,符合第二种重载
add('hello','world')//符合第一种重载
add(1,'ss')//报错,不符合重载类型
泛型(generic)
泛型
用来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
function fun<T>(x: T,y:number): T {
return x;
}//将类型设置成类似于变量的形式,这样以后再用的时候就可以根据不同的数据类型,使用不同的参数
fun<string>('xx',12)//可以
fun<string>(123,12)//可以
fun<number>('ss',12)//报错
类型别名 type
type作用就是给类型起一个新名字,支持基本类型、联合类型、元组及其它任何你需要的手写类型
例子:
type test = number; //基本类型
let num: test = 10;
type userOjb = {name:string} // 对象
type getName = ()=>string // 函数
type data = [number,string] // 元组
type numOrFun = Second | getName // 联合类型
全文尽量简短快速的概括了TS的常用点,目的在于用最短的时间先了解ts,再学会如何去用。
接下来的文章,将会结合使用具体使用时,从一些成熟的TS框架(如Vue3-ts和nestjs)或者日常使用中来看看TS是怎么用的。(我一直秉持着想学会怎么用就看看别人怎么用的观点🤣)
对了,如果你喜欢这个系列,不妨关注我,一起学习,一起进步!