目录
一、TypeScript是什么
TypeScript 是一种由微软开发的开源编程语言。它是 JavaScript 的一个超集,意味着它在 JavaScript 的基础上增加了类型系统和一些其他特性。TypeScript 的设计目标是开发大型应用程序,通过静态类型检查来提高代码的可维护性和稳定性。
二、TypeScript与JavaScript区别
三、基本类型
1.布尔类型boolean
const isDone: boolean = false;
// ES5:var isDone = false;
2.数值类型number
const count: number = 10;
// ES5:var count = 10;
3.字符串类型string
双引号或者单引号表示字符串
模板字符串使用反引号来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法 ${xxx} 的占位符,占位符内可以写变量名,模板字符串会进行变量值的解析。
const title: string = "你好,张三";
// ES5:var title = '你好,张三';
4.数组类型array
数组类型有两种表示方法,第一种在元素类型后接上[],表示由此类型元素组成的一个数组。
const list: number[] = [1, 2, 3];
// ES5:var list = [1,2,3];
另一种方式是使用数组泛型,Array<元素类型>。
const list: Array<number> = [1, 2, 3]; // Array<number>泛型语法
// const list: ReadonlyArray<number> = [1, 2, 3]; // 数组不可被修改
// ES5:var list = [1,2,3];
5.枚举类型enum
enum Gender {
man,
woman
}
console.log(Gender[0]);
console.log(Gender[1]);
console.log(Gender['man']);
console.log(Gender['woman']);
enum Direct {
n = 'north',
s = 'south',
w = 'west',
e = 'east'
}
console.log(Direct['n']);
console.log(Direct['s']);
console.log(Direct['w']);
console.log(Direct['e']);
6.any类型
let str: any = 666;
str = "你好,李焕英";
str = false;
7.元组类型Tuple
类似于数组,但是里面的元素可以是不同类型的
var user: [string, number, string, Array<string>] = ['成龙', 66, '男', ['html', 'css', 'javascript']]
//ES5:var user = ['成龙', 66, '男', ['html', 'css', 'javascript']];
8.void类型
function fn1(): void {
// return 123
}
9.null 和 undefined 类型
let u: undefined = undefined;
let n: null = null;
10.never 与 unknown类型
never异常的数据类型。
// 函数里有死循环那么返回的也是never
function infiniteLoop(): never {
while (true) {}
}
unknow是any的安全类型
var value: unknown //可以把unknow类型的变量赋任何有效的值
value = 1 //ok
value = '' //ok
value = true //ok
value = [] //ok
var value1: any = value //ok
var value2: unknown = value //ok
// var value3:string=value //Error
11.字面量类型
字面量类型,通常和联合类型一起使用,表示类型或的关系
var sty: 'ls' = 'ls'
var num: 22 = 22
var bool: true = true
type EventType = 'click' | 'dbclick'
var ev: EventType = 'click'
document.body.addEventListener(ev, function () {
})
四、高级类型
1.联合类型
就是js中的短路或,要么是A类型,要么是B类型
function getSum(a:number|string,b:number|string):number{
return +a + +b
}
console.log(getSum(1,2));
console.log(getSum('1','2'));
2.交叉类型
就是数学里的并集,既有A类型的属性或方法,也有B类型中的属性或方法。
interface IUser{
id:number,
name:string
}
interface IInfo{
score:number
}
var user1:IInfo&IUser={
id:0,
name:'李世民',
score:99
}
3.可选类型
可选类型,使用工具类型中的Partial让对象中所有的类型变成可选。
interface IStudent{
id:number
name:string
score:number
}
var s1:Partial<IStudent>={
id:0,
name:'李连杰'
}
4.条件类型
相当于js中的三元/三目表达式,只不过求的是类型
interface Fish{
name1:string
}
interface Wate{
name2:string
}
interface Bird{
name3:string
}
interface Sky{
name4:string
}
type TAnimal<T>=T extends Fish?Wate:Sky
var animal:TAnimal<Bird>={
// name1:'天空' //ts编译器:对象字面量只能指定已知的属性,但“name1”中不存在类型“Sky”。是否要写入 name4?
name4:'天空'
}
5.映射类型
其实就是把一个对象属性的类型处理成另一个对象属性的类型,他们是一一对应的关系。
type User2={
name?:string
location:string
age?:string
}
//keyof User => name | location | age
//P in keyof User:p是一个类型变量,判断是否属于 name | location | age三个属性中的一个
type MyCopy<T>={
[p in keyof T]:T[p]
}
type MyPartial<T>={
[p in keyof T]-?:T[p]
//上面一行代码执行结果就是下面三行代码
// name:string
// location:string
// age:string
}
五、函数
1.函数
函数的类型签名:在函数中涉及到数据的地方只有参数和返回值,所以在ts中的函数就是对形参和返回值做类型签名。
基本使用:相当于把ts在的基础类型、高级类型以及其它类型结合起来使用。
function User1(id:number,name:string):void{
}
索引签名:声明的时候无法知道属性名及类型,在使用的时候才知道属性名和类型。
interface IStudent1{
id:number
name:string
[a:string]:unknown//a是一个变量,代表的是属性的名称
}
var s2:IStudent1={
id:0,
name:'ls',
sex:'男'
}
六、对象/接口
1.函数类型
使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
interface SearchFunc {
(source: string, subString: string): boolean;
}
const mySearch: SearchFunc = function(src: string, sub: string) {
return Math.random() > 0.5
}
2.类类型
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date): void {
this.currentTime = d;
}
constructor(h: number, m: number) { }
}
3.继承接口
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
4.混合类型
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = <Counter>function (start: number) { };
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
七、类型别名
类型别名:很多场景下和interface是一样的,但是类型别名适用的场景更广泛,它不会生成新的类型,但是类型别名的语义性(可读性)不高,所有官方推荐优先适用interface。
type User4=string|number
type blean=true|false
const ages:User4=12
type TUser={
name:string
age:number
}
const tuser:TUser={
name:'zs',
age:22
}
interface Iuser{
name:string
age:number
}
八.类型守卫
1.in 关键字
interface Inobj1{
name:string
age:number
}
interface Inobj2{
name:string
sex:string
}
function getobj(arg:Inobj1|Inobj2):void{
if('age' in arg) console.log('age');
if('sex' in arg) console.log('sex');
}
getobj({name:'ls',age:11,sex:'男'})
2.typeof 关键字
function isTypeof( val: string | number) {
if (typeof val === "number") return 'number'
if (typeof val === "string") return 'string'
return '啥也不是'
}
3.keyof关键字
keyof是关键字,用于从对象类型中提取键类型。 tips:对象是用键值对表示的
interface Person {
id: number
name: string
age: number
}
type P1 = keyof Person // 'id' | 'name' | 'age'
type P2 = Person[P1] // 'number' | 'string'
4.instanceof 关键字
function creatDate(date: Date | string){
console.log(date)
if(date instanceof Date){
date.getDate()
}else {
return new Date(date)
}
}
九、class类
1.类的本质
class Animal1{
constructor(type:string){
this.type=type
}
move(){
console.log(`我是${this.type},我会动`);
}
}
const a1=new Animal1('爬行动物')
a1.move()
2.类的继承
class Animal1{
constructor(type:string){
this.type=type
}
move(){
console.log(`我是${this.type},我会动`);
}
}
class People1 extends Animal1{
name:string
constructor(name:string,type:string){
super(type)
this.name=name
}
run(){
console.log(`我是${this.name},我会跑`);
}
}
const a1=new Animal1('爬行动物')
a1.move()
const p2=new People1('张三丰','哺乳动物')
p2.run()
3.类方法重载
类方法重载,其实就是函数重载,同一个函数名根据不同的传参类型执行不同的操作。
class Coder {
coding(): void
coding(type: string): void
coding(type: string[]): void
// 上面是方法的声明
coding(type?: string | string[]) {
if(typeof type === 'string') {
console.log('我会写'+type)
} else if(!type) {
console.log('我会敲代码')
} else {
console.log('我会写'+type.join(','))
}
}
}
const c = new Coder()
c.coding()
c.coding('javascript')
c.coding(['html', 'css', 'javascript'])
4.类的访问修饰符
class Animal1{
//类的访问修饰符:作用是对类中的成员属性和成员方法做权限设置
public readonly type:string//public任何地方都可以使用,readonly表示只读,无法修改
private body:boolean=true// private只有该类内部通过this使用
//如果类里的成员属性没有初始值,而是通过实例化的时候传入,此时需要使用constructor
//如果类里的成员属性有初始值,可以不用写constructor
constructor(type:string){
this.type=type
}
protected move():void{
console.log(`我是${this.type},我会动`);
}
jump():void{
// this.body
console.log(this.move());// protected修饰符 允许在父类内部和继承类内部使用
}
}
const a1=new Animal1('爬行动物')
// a1.move() //protected修饰的方法不能直接调用
a1.jump()
十、装饰器Decorator
//类装饰器
//本身是一个函数,返回的也是一个函数
function log(params: string) {
console.log(params);
return (target: any) => {
console.log(target);
}
}
//方法装饰器
function log1(params: string) {
console.log(params);
return (target: any, name: any, descriptor: any) => {
console.log(target, name, descriptor);
}
}
@log('类装饰器传入的参数1')
class People1 {
name: string = 'zs'
constructor(name: string) {
console.log('构造函数');
this.name = name
}
@log1('方法装饰器的参数') say(): void {
console.log('hello');
}
}
const p1 = new People1('ls')
console.log(p1.name);
十一、命名空间
单例设计模式其实就是给一些数据添加到一个命名空间,方便统一维护管理。
命名空间使用namespace声明,外面如果需要使用到命名空间里的类型,需要给命名空间里的类型加上export。
//js中的命名空间
const o1={
name:'zs',
age:12,
say(){},
study(){},
coding(){}
}
namespace demo{
export interface Iuser3{
name:string
age:number
}
}
const u3:demo.Iuser3={
age:12,
name:'zs'
}