TypeScript学习笔记

TypeScript

  • 是以javascirpt为基础构建的语言,可以在任何支持JavaScript的平台执行。
  • 是javascript的一个超集,对js进行了扩展,将js动态类型转换成了静态类型。
  • TS不能被JS解析器直接执行,需要通过编译,将ts转换为js再执行。
// 变量类型固定了,即初始变量的类型是什么,就是什么了,不会再变。
let a = '11'
a=6 //不行,a只能是string型

TypeScript开发环境的搭建

  1. ts解析器(将ts转换为js)是用node.js写的,所以先安装node.js
  2. 使用npm全局安装typescript解析器:npm i -g typescript
  3. 写ts文件,然后编译ts文件命令:tsc xxx.ts ,将ts编程成js,然后运行js文件
  4. 简化ts步骤 安装ts-node包命令:npm i -g ts-node
  5. ts-node xxx.ts 在内部将ts转换成js,然后自动执行js,但并不会生成js文件。

TypeScript语法

类型声明(类型注解)

  • let 变量: 类型;
  • let 变量: 类型 = 值;
  • function 函数名(参数:类型, 参数:类型): 类型{ …}
  • 类型注解作用:为变量添加类型约束,即约定了什么类型,就只能给变量赋值该类型的值
  • ts有自动类型判断机制,当变量声明和赋值是同时进行时,可以省略类型声明。即 let 变量 = 值;
//声明一个变量a,并且类型为number
let aa: number;
aa=10;  //正确
aa='hh'//错误

// 自动类型判断
let b=true;

function fn(a: number,b: number): number{
	return a+b;
}
fn(111,'222')//报错
fn(111,222,333)//报错

JS已有类型

类型例子描述
number1, -2, 3.5任意数字
string‘hi’, “hi”任意字符串
booleantrue, false布尔值true或false
nullnull
undefinedundefined未定义
symbolSymbol(“a”)表示独一无二的值
object{name: ‘zhangsan’}任意JS对象(如数组,对象,函数)
基本类型
let age: number = 16;
let name: string = 'zhangsan';
let flag: boolean = false;
let a: null = null;
let b: undefined = undefined;
let c: symbol = Symbol();
let o: symbol = Symbol();
对象(数组类型)

let numbers: number[] = [1,3,5] //推荐
let names: Array<string> = ['a','b','c']
对象(函数类型)
  • 给函数加类型实际上是给函数参数返回值加类型
// 单独指定参数、返回值类型
function fn(a: number,b: number): number{
	return a+b;
}
const fn1 = (a: number,b: number): number =>{
	return a+b;
}

// 同时指定参数、返回值类型(只适用于函数表达式 =>)
// const fn2= (a,b) => {return a+b;}
// [: (a: number,b: number)=> number ]
const fn2: (a: number,b: number)=> number = (a,b) => {return a+b;}

//可选参数,在参数后面加上?,可传可不传参数只能出现在参数列表后面,或必选参数后面
function fn3(a: number,b?: number): void{
	console('a:',a,'b:',b);
}
fu3(1,2) //参数可以传
fu3(1) //参数可以不传
对象类型
// {name: string; age: number}
let person: {name: string; age: number; sai(name: string): void} = {
	name: 'zhangsan',
	age: 19,
	sai(nae){}
}

//对象的属性和方法,也可以是可选的,加上?就可以了
function may(config: {url: string; method?: string}) {
	console.log(config)
}

may({url:'www'})

TS新增类型

类型例子描述
字面量其本身限制变量的值就是该字面量的值
联合类型--
any*任意类型
unknown*类型安全的any
void空值或undefined空值或undefined
nerver没有值不能是任何值
tuple元组[4,5]元素,固定长度数组
enumenum(A,B)枚举
字面量
  • 使用字面量进行类型声明(用来表示一组明确的可选列表)
let a1: 10; //a1的类型就是10
a1=10; //赋值10
a1=12; //报错a只能赋值10
const str1 = 'hello'  //str1的类型就是hello
let str2: 10|11|12; //str2的值只能赋值是10 11 12
联合类型
  • 用 | 线连接多个类型(联合类型)
let a2: 10 | 11;
// 有小括号表示是string数组或number数组
let names: (string | number)[] = [1,'a','b','c']
// 没有小括号表示是number或string数组
let names:  number |string[] =123
any(任意类型)
  • any(任意类型),一个变量设置了any后,相当于对该变量关闭了类型检测
let a3: any;
a3=10;
a3='10'
let b2; //声明变量不赋值,默认是any类型,即隐式any
let b3: string = a3 //可以将any类型赋值给任意变量不会报错
unknown
  • 表示未知类型的值
let a4: unknown;
a4=10;
a4='10'
let b4: string
b4 = a4 //不可以将unknown类型赋值给其他的变量,会报错
b4 = a4 as string //如果一定要赋值用类型断言,告诉解析器变量实际的类型:变量as类型
b4 = <string>a4 //或者:<类型>变量
void
  • 主要用于函数,表示该函数没有返回值,表示空值(undefined)
function fn(): void{
	return;
	// return undefined; 也行
	// return null; 也行
}
never
  • 主要用于函数,表示该函数永远不会有返回值,表示没有值(undefined都没有)
function fn(): never{
	throw new Error('报错了'); //函数报错了就没有返回值,连undefined都没有
}
元组
  • tuple元组 固定长度数组,例如用来表示经纬度坐标
let position: [number,number] = [39.55,116.23] //该例子数组只能由两个元素,并且都是number
枚举
  • 使用enum关键字
  • 枚举中的值以大写字母开头,多个值用逗号分隔
  • 表示一组明确的可选值,定义一组命名常量
  • 枚举成员是有值的,默认为:从0开始自增的数值,称为数字枚举。
//定义枚举类型
//Up-->Right 值0,1,2,3
enum Des {Up,Down,Left,Right} 
function chage(dire: Des){}
//访问枚举成员
chage(Des.Up)

//设置枚举成员的值
//Up-->Right 值10,11,12,13
enum Des {Up=10,Down,Left,Right} 
enum Des {Up=10,Down=12,Left=14,Right=16} 

//字符串枚举(没有自增行为,因此每个成员必须要有初始值)
enum Des {Up='Up',Down='Down',Left='Left',Right='Right'} 

类型别名(自定义类型)

  • 类型别名可以为任意类型起别名,当同一复杂类型被多次使用,可以起类型别名,简化使用
//关键字type
type CustomType = (number | string)[]
let arr1: CustomType = [1.'2',3]

接口

  • 当一个对象类型被多次使用时,一般会使用接口来描述对象的类型
  • 使用interface关键字来声明接口
  • 因为没一行只有一个属性,所以属性类型没有;
//接口
interface IPerson{
	name: string
	age: number
	sai(name: string): void
}

let person: IPerson = {
	name: 'zhangsan',
	age: 19,
	say(){}
}

//interface接口和type类型别名都可以给对象指定类型,但接口只能为对象指定类型,类型别名可以为任意类型指定别名
type IPerson1{
	name: string
	age: number
	sai(name: string): void
}
接口继承(extends)
interface Person{
	name: string
	age: number
}
// IPerson继承了Person中所有的属性
interface IPerson extends Person{
	sai(name: string): void
}

类型推断

//(1)声明变量并初始化时
let age = 16
//(2)决定函数返回值时
function add(num1: number,num2: number){return num1+num2}

类型断言

  • 语法个数:as或者<>
let a4: unkown;
let b4: string
b4 = a4 as string //如果一定要赋值用类型断言,告诉解析器变量实际的类型:变量as类型
b4 = <string>a4 //或者:<类型>变量 了解就行

const alink = document.getElementById('link')as HTMLAnchorElement
const alink1 = <HTMLAnchorElement>document.getElementById('link')

typeof

  • 可以在类型上下文中引用变量或属性的类型(类型查询)
let p ={x:1,y:2}
//point:后面是类型的声明,也就是类型上下文
function forp(point: typeof p){}
forp({x:10,y:100})

//可以查看对象属性的类型
let a: typeof p.x;//a的类型为number
let ret: typeof forp({x:10,y:100}) //报错,不可以查看函数调用的类型

class类型

class Person{
	//属性
	name: string //声明但不赋值
	age = 16      //声明并赋值
	//构造函数不需要返回值类型
	constructor(name: string, age: number){
		this.name = name
		this.age = age
	}
	//方法
	sayi(n:number):void{
		console.log(n)
	}
}
const p = new Person()//代表当前常量p的类型是Person

类的继承和接口的实现
  • 继承:extends
  • 实现:implements
class MyPerson extends Person implements IPerson {}
类的可见性修饰符
  • public:公有成员可以被任何地方访问,默认是public,可以省略
  • protected:表示受保护的,仅对其声明所在类和子类(非实例对象)可见
  • private:表示私有的,仅在当前类中可见,对实例对象以及子类都是不可见的。
  • readonly:只读修饰符。用来防止构造函数之外对属性进行赋值,只能修饰属性不能修饰方法
class Person{
	readonly name: string ='zhangsan' //必须加上string,否则就变成字面量类型了
	constructor(name: string){this.name =name}
	readonly type(){ //错误
		this.name='li'//错误
	} 
}

//也可以在接口中指定属性为只读
interface IPerson{
	readonly name: string
}

let obj: {readonly name: string}={name: 'zhangsan'}
class Person{
	private name: string =null
	constructor(name: string){this.name =name}
}
// 上面的写法和下面的写法是等价的
class Person{
	constructor(private name: string){}
}

类型兼容性

  • TS是 structural type system 结构化类型系统
class的类型兼容性
class Point {x:number,y:number}
class Point2 {x:number,y:number}

const p: Point = new Point2() //正常,因为只检查Point和Point2的结构是否相同
class Point {a:number,b:number} //x
class Point2 {a:number,b:number,c:number} //y

//对于对象类型来说,y的成员至少与x相同,则x兼容y(成员多的可以给成员少的赋值)
const p: Point = new Point2() 
接口的类型兼容性(和class一样)
interface Point {a:number,b:number} //x
interface Point2 {a:number,b:number,c:number} //y
const p: Point = Point2

//class和interface之间也可以兼容
class Point2 {a:number,b:number,c:number} //y
const p: Point = new Point3()
函数之间的兼容性
  • 参数个数:参数少的可以赋值给参数多的,因为js中可以省略用不到的参数
type F1 = (a:number) => void
type F2 = (a:number,b:number) => void
let f1:F1
let f2:F2 =f1 
  • 参数类型:相同位置的参数类型(原始类型)要相同或(对象类型)要兼容
// (原始类型)要相同
type F1 = (a:number) => void
type F2 = (a:number) => void
let f1:F1
let f2:F2 =f1

// (对象类型)要兼容
// 从接口角度看是冲突的,技巧,将对象拆开,把每一个属性看做一个个参数。
interface Point {a:number,b:number} 
interface Point2 {a:number,b:number,c:number} 
type F1 = (a:Point) => void
type F2 = (a:Point2) => void
let f1:F1
let f2:F2 =f1
  • 返回值类型:只关注返回值类型本身即可,返回类型(原始类型)要相同或(对象类型)要兼容
// (原始类型)
type F1 = () => number
type F2 = () => number
let f1:F1
let f2:F2 =f1

// (对象类型:按照对象的兼容规则)成员多的赋值给成员少的
type F1 = () => {a:number,b:number} 
type F2 = () => {a:number,b:number,c:number} 
let f1:F1
let f2:F2
f1=f2

交叉类型

  • 交叉类型 & :功能类似接口继承,用于组合多个类型为一个类型常用于对象
interface Point {fn:(a:number)=>number} 
interface Point2 {b:number;fn:(a:string)=> string} 
type Per = Point & Point2
// Per可以理解为{fn(a:number|string)=>string}
let obj: Per = {
	fn(number){}
	b: 2
}

泛型

创建泛型函数
  • function id(value:Type):Type{return value}
  • 在函数名称后面加 <> 尖括号中添加类型变量
  • 常用于函数、接口、class
function id<Type>(value:Type):Type{return value}
const num = id<number>(10)
const num = id(10) //<类型>可以省略,因为有类型参数推断机制
const str = id<string>('a')
泛型约束
  • 指定更加具体的类型
  • 添加约束
function id<Type>(value:Type[]):Type[]{return value.length //就可以访问value的length属性了}
interface ILegnth {length : number}
function id<Type extends ILegnth >(value:Type):Type{return value.length}
  • keyof关键字接收一个对象类型,生成其键名称的联合类型
function id<Type, Key extends keyof Type>(obj:Type,key:Key):Type{return obj[key]}
let per={name:'jack,age:16} //生成其键名称的联合类型 "name"|"age"
id(per,'name') //其中第二个参数必须是第一个参数的键的其中一个,此处可以是'name'也可以是'age'
泛型接口
  • 在接口后面添加<类型> 就是泛型接口
  • 没有类型参数推断机制,使用接口时需要显示指定具体的类型
  • 数字就是一个泛型接口
interface IdFunc<Type> {
	id:(value: Type) => Type
}

let obj: IdFunc<number> = {
	id(value){return value;}
}
泛型类
  • 在类后面添加<类型> 就是泛型类
  • 声明的时候 <类型>可以传也可以不传
class Func<Type> {
	id:(value: Type) => Type
}

let Nu = new func<number>();
泛型工具类型
  • Partial< Type > 用来构造(创建)一个类型,将Type的所有属性设置为可选
  • Readonly< Type > 用来构造(创建)一个类型,将Type的所有属性设置为readonly(只读)
  • Pick<Type , keys> 从Type中选择一组属性来构造新类型
  • Record<Keys,Type> 构造一个对象类型,属性键为keys,属性类型为Type
  • 都是内置的可以直接使用
interface Prop {
	id: string,
	chid: number[],
	title: string
}

//构造出来的新类型Pars结构和Prop相同,但所有属性变为可选
type Pars =Partial<Prop>
let par: Pars={id:'1'}//正常,属性是可选的,所以chid和title可以不传

type Pars2 = Readonly<Prop>
let par2: Pars2={
	id:'1',
	chid: [],
	title: ''
}
par2.id=2 //报错,属性是只读属性

//构造的新类型只有id和chid属性, 没有title属性
type Pars3 = Pick<Prop, 'id'| 'chid'>

type Pars4 = Record<'a'|'b'|'c',string[]>
let obj: Pars4 = {
	a:['1'],
	b:['2'],
	c:['3']
}

索引签名类型

  • 当无法确定对象中有哪些属性时,或任意多个属性时,用索引签名
  • [kk:string] 来约束接口中允许出现的属性名称
  • kk只是一个占位符,可以是任意合法的变量名称
  • 数组的键是数值类型的
interface Ansy{
	[kkee:string]: number
}

let obj: Ansy ={
	a:1,
	b:2
}

//数组的键是数值类型的
interface MyArray<T>{
	[n: number]: T
}

let arr: MyArray<number> = [1,2,3]

映射类型

  • 基于旧类型映射新类型
  • 只能在类型别名中使用,不能在接口中使用
type Prop = 'x'|'y'
//key表示可以是Prop类型中的任意一个
type Tye = {[key in Prop]:number}

type Prop2 ={a:number,b:string}
type Tye2 = {[key in keyof Prop2]: number}

索引查询(访问)类型

  • T[P]
type Prop ={a:number,b:string}
type Tye =Prop['a'] //Tye 的类型为number
type Tye =Prop['a'|'b'] 
type Tye =Prop[keyof Prop] 

类型声明文件

  • 用来对已存在的JS库提供类型信息
  • .d.ts文件就是类型声明文件(只包含类型信息),不会生成js,仅为js提供类型信息
  • 由DefinitelyTyped提供的第三方类型声明文件,包的名称格式为@types/…,比如@types/react
  • 下载类型声明文件 npm i --save-dev @types/…
创建类型声明文件
  1. 创建index.d.ts文件
  2. 创建需要共享的类型,并使用export导出
  3. 在需要使用共享类型的.ts文件中通过import导入
// index.d.ts
type Props = {x:number,y:number}
export{Props}
// index.ts
import {props} from './index'
let p1: Props = {
	x:1,
	y:2
}
// index2.d.ts
//为已存在的变量声明类型
declare let count: number
// index2.js
let count = 10

React

  • npx create-react-app 项目名称 --template typescript
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值