typescript的基本语法
typescript
typescript 是js的超集,静态类型检测
命令:
//监听ts文件的变化
$ tsc -p tsconfig.json --watch
原始类型
为了使文件里的变量不污染全局
//在第一行增加
export {};
string
let str:string = "2" //string
number
let num:number = 1 //number
boolean
let bool:boolean = true //boolean
null
let nul:null = null; // null
undefined
let undef: undefined = undefined; // undefined
symbol
let sy: symbol = Symbol(); // symbol
void
let vd: void = undefined; // 可以把undefined类型赋值给void类型,但是反过来不行
// 函数没有返回值,那么函数的返回值类型就是voidfunction fn(): void {return undefined;
}
非原始类型
object
不能是string,number,boolean,symbol,严格模式:多包括null,undefined
let obj7:object = {a: 1, b: '2'};//对象
let obj8:object = [1, 2, 3]; //数组
Object
Object是object类型子类型
包含了原始类型和非原始类型
代表所有拥有 toString、hasOwnProperty 方法的类型,所以所有原始类型、非原始类型都可以赋给 Object,严格模式下不包括null,undefined。{}空对象类型和大 Object 一样。
let a5:Object = 1
let a6:Object = []
let a7:Object = {}
let a8:Object = function(){}
{ }
{ }和Object范围类型一样
let a9:{} = 1
let a10:{} = [1,2,3]
let a11:{a:number,b:string} = {a:1,b:"1"}
let a12:{} ={}
数组类型
定义数组的方式
方式一:直接定义
let arr :number[] = [1,2,3]
arr[3] = 4
方式二:元组
// 元组:固定元素长度的数组,用数组的方式可以拓展
let arr1:[number,string,boolean] = [1,"2",true]
// arr1[3] = 3 //报错
arr1.push(2)
方式三:Array接口类型::泛型,类型参数化
Array<类型>
//例如:
let arr1: Array = [1, 2, 3];
arr1.push('3'); // 报错
arr1.push(5);
let arr2: string[] = ['4', '5', 'a'];
arr2[3] = '6';let arr3:Array<{}> = [1,"1",true]
let arr4:Array
字面量类型
const
//定义的不可以修改const a11:1 = 1
let str:"2" = "2"
// let str1:"2" = "1" //报错
let bool:true = true
TypeScript 支持 3 种字面量类型:string字面量类型、number字面量类型、boolean字面量类型
联合类型 |
用 | 表示可能的类型
let arr:(number | string | boolean)[] = [1,"2",true]let a:number|string = 1;
a = "2"
交叉类型 &
用 & 表示 必须拥有全部
let a2:number & string //既要满足number类型,也要满足string类型的值 (没有一个这样的值)
let obj:{age:number} &{name:string} = {age:12,name:"张三"}
组合
let obj1:({age:number} | {height:200}) & ({name:string} | {wight:400}) = {age:200,name:"张三"
}obj1={age:160,name:"李四",height:200
}
any
指的是一个任意类型,它是官方提供的一个选择性绕过静态检测的作弊方式。非常不建议使用: (any是地狱)
let a:any =1;
a="2"
a={}
a.toFixed(1)
unknown
unknown 是typeScript 3.0中添加的一个类型,它主要用来描述类型并不确定的变量,和any的区别就是会进行类型检测。
let b:unknown;
b=1;
b="2";
b=undefined;
b={};// b.toFixed(1)//报错,因为此时b的类型不确定
as 断言
// as 断言,确定b的类型
(b as number).toFixed(1)
never类型
never表示永远不会发生值的类型
function throwErrFn():never {throw new Error('出错了');
}// 1. **如果函数里是死循环,返回值类型也是never **
// 2. **never 是所有类型的子类型
接口 interface
定义一个类型
interface PersonInfoItf {name:string;age:number;[key:string]:number | string;
}
let obj:PersonInfoItf={name:"",age:12}
let obj1:PersonInfoItf={name:"111",age:12}
let obj2:PersonInfoItf={name:"",age:12,a:1}
定义一个数组
let arr:(number| string)[] = [1,2,3,"4"]interface ArrItf {[idx:number] : number | string
}
let arr1:ArrItf = [1,2,3,"4"]
定义没有固定属性的对象接口类型
interface ObjItf{[key :string] : string | number
}
let arr2:ObjItf = {a:1,b:2,c:3
}
定义函数类型
let fn:() => void = ():void => {console.log(11)
}interface FnItf {(a: string):void
}
let fn1:FnItf = (a):void => {console.log(11)
}//**很少使用接口类型来定义函数的类型,更多使用内联类型或类型别名配合箭头函数语法来定义函数类型;**
接口继承
多个不同接口之间是可以实现继承的,但是如果继承的接口PersonInfo和被继承的接口NameInfo有相同的属性,并且类型不兼容,那么就会报错。
多个接口组合成一个新的接口
interface PersonInfoItf{name:string
}interface OtherInfoitf {age:number
}interface MaleItf extends PersonInfoItf,OtherInfoitf{}let person:MaleItf = {name:"",age:12
}
多个相同的接口
多个相同接口,相同名字的接口类型,里面的属性会进行合并
interface A {name:string
}
interface A {age :number// name:number ; //报错,上面已经定义了
}let a :A = {name:"",age:12
}
用处:扩展第三方库的接口
可缺省和只读属性修饰
可缺省:用 ?表示
只读:用 readonly 表示,写在只读的属性前面
interface B {readonly name:string;age?:number
}let b:B = {name:""} //age 可缺省,有没有都行
// b.name = "123"//报错 ,因为name属性只读let c:B = {name:"",age:12}
类型别名
interface接口类型不支持联合类型和交叉类型
类型别名 type 类型名 = 具体类型值
type ThreeTypes = string | number | boolean;
let a:ThreeTypes = 1
let b:ThreeTypes = "1"
let c:ThreeTypes = truetype PersonType = {name:string} & {age :number}
let a1:PersonType = {name:"",age:12
}
用处或者用法:类型别名可以针对接口没法覆盖的场景,例如组合类型、交叉类型等;
// 类型别名是不能拿重名
// type ArrType = Array //报错 重名了
type ArrType = {[idx:number]:number | string}// 函数定义
type Fntype = () =>number
let fn:Fntype = ()=>{return 1}
let fn1:() =>number = ()=>{return 1}
函数类型
函数类型定义
function fn():undefined{return undefined}
function fn1():void{};
function fn2(a:string,b:number):void{}
接口定义函数类型
interface FnItf{(a:string,b:number):void
}// let fn3:FnItf = (a,b) =>{}//a 和 b 代表的是参数
let fn3:FnItf = (b,a) =>{}
类型别名定义函数类型
type Fntype = ()=>{name:string}
let fn4:Fntype=()=>({name:""})
声明函数类型
declare function fn5():void;
函数的参数类型
// ?可选参数 意思是不传
function fn(a:string,b?:number){}
fn("",1)
fn("")
// fn()//报错// 设置函数参数默认值
function fn1(str:string="123"){}
fn1()
fn1("123456")// 剩余参数
// 解构
function fn2(...arr:number[]){}
fn2(...[1,2,3])
fn2(1)
fn2(1,2,3,4,5)
this
在Typescript中,必须要明确的指定this的类型(严格模式下)。
type ObjType = {name:string};function fn(this:ObjType,a:string){console.log(this);}let obj:ObjType = {name:""};
// fn.apply({})//报错 { } 值不符合ObjType的类型
fn.apply({name:""},[""])
fn.apply(obj,[""])
枚举
枚举的作用在于定义被命名的常量集合,一个默认从 0 开始递增的数字集合,称之为数字枚举。也可以指定值,这里可以指定的值可以是数字或者字符串。
enum StatusCode{NotLogin = -1,Success,Exprie
}
//自动会补全+1 number类型// 假设后端返回的状态码是变量res
let res:number = 0;if(res===StatusCode.NotLogin){console.log("没登录");
}else if(res===StatusCode.Success){console.log("登录成功");
}else if(res===StatusCode.Exprie){console.log("登录已过期");
}console.log(StatusCode.Success,StatusCode.Exprie);
泛型
指的是类型参数化,即将原来某种具体的类型进行参数化。
let arr:Array<number | boolean | string> = [1,true,""]let arr1:Array<number>=[1];
function fn(a:unknown){}
fn(1)
fn("")
fn(true)function fn1(p:number):number{return p
}
function fn2(p:string):string{return p
}
function fn3(p:boolean):boolean{return p
}type parmsType = number | string | boolean;function fn5(p:parmsType):parmsType{return p
}
泛型函数定义
function fnn<S,P=string>(p:P,s:S):P{return p
}fnn<number>("",1)
fnn<string>("","")type ObjType = {n:string}
fnn<ObjType,number>(1,{n:""})
fnn("","")// fnn(p: "", s: string): ""
泛型类型
// 定义数组类型
let arr: Array<number> = [1];
let arr1: Array<string> = [""];// 类型别名
type typeFn<P> = (params: P) => P;
let fntype: typeFn<number> = (n: number) => {return n;
};let fn1:typeFn<string> = (p: string):string => {return p;
}
// 定义接口类型
interface TypeItf<P> {name: P;getName: (p: P) => P;
}let t1: TypeItf<number> = {name: 123,getName: (n: number) => {return n;},
};let t2: TypeItf<string> = {name: "123",getName: (n: string) => {return n;},
};
泛型约束
把泛型入参限定在一个相对更明确的集合内,以便对入参进行约束。
// T只接受number & string
interface ObjItf<T extends string | number> {name:T;getName:(n:string)=>string
} let obj:ObjItf<number> ={name:1,getName:(n:string)=>{return n}
}
类的定义使用
// 在定义类的同时,除了定义的这个类,也创建了一个接口,接口的名字就是类名Personclass Person{// 成员属性:类型name:string="张三"
}let p:Person = new Person();
let obj:Person={name:""
}class Male {name:string;age:number;constructor(name:string ,age:number){this.name = name;this.age = age}say(this:Male,song:string){console.log(song);return this}
}let m = new Male("张三",20)
console.log(m.say("唱歌").name);
console.log(m.name,m.age);let m1 = new Male("李四",100)
console.log(m1.say("跳舞").name);
console.log(m1.name,m1.age);
继承
使用extends关键字实现继承
// 类中常用修饰符
// public:公用的,默认类中的属性和方法都是public修饰的,基类,子类,类外部都可以访问
// protected:受保护的,基类,子类都可以访问,类外部不可以访问
// private:私有的,基类可以访问,子类,类外部都不可以访问
// readonly:只读(不能修改)class Person{public name:string;protected readonly weight:string="50kg";private heigth:string = "150";constructor(name:string){this.name = name}say(){// this.weight = "" ;只读属性不能被修改// 可以在当前的类中访问自己的public修饰的成员属性console.log(this.name,this.weight,this.heigth);}
}let p = new Person("张三")
p.say()
console.log(p.name);
// 受保护和私有的属性不能在类的外部访问,p.weightclass Male extends Person{age:number;constructor(name:string,age:number){super(name);this.age = age}say(): void {console.log("子类"+ this.name + this.weight);// 子类不能访问父类的private修饰的属性}
}let m = new Male("李四",22)
console.log(m.name,m.age);
静态属性
基于静态属性的特性,往往会把与类相关的常量、不依赖实例 this 上下文的属性和方法定义为静态属性,从而避免数据冗余,进而提升运行性能。
class Person{name!:string;// 静态成员static readonly age:number = 10;
}let p = new Person();
console.log(p.name);
// 访问静态成员
console.log(Person.age);
抽象类和接口
抽象类,它是一种不能被实例化仅能被子类继承的特殊类。
abstract class Person1{abstract name:string;abstract say():void;run(){console.log("跑");}
}class Male extends Person1{name: string = "zhsngan";say(): void {console.log("抽象方法say");}
}let m = new Male();
m.name;
m.say();
m.run();// 接口
interface Person2{name:string;age:number;say:()=>void
}class Female implements Person2{name: string = "";age: number= 20;weight:string = "200"say(){}
}
// class F1 implements Person2 {
// name: string;
// age: number;
// say: () => void;// }
修饰符
public、private、protected、readonly
在 TypeScript 中就支持 3 种访问修饰符,分别是 public、private、protected。通过这三个修饰符做到控制属性和方法的访问。
- public:基类、子类、类外部都可以访问;
- protected:基类、子类可以访问,类外部不可以访问;
- private:基类可以访问,子类、类外部不可以访问;
- readonly:只读修饰符
class Person {public readonly name: string = '张三';protected age: number = 20;private height: string = '180';protected getPersonInfo():void {console.log(this.name, this.age, this.height); // 基类里面三个修饰符都可以访问}
}class Male extends Person {public getInfo():void {console.log(this.name, this.age); // 子类只能访问public、protected修饰符的}
}let m = new Male();
console.log(m.name); // 类外部只能访问public修饰的
m.name = '李四'; // name属性使用只读修饰符,所以不能对name进行赋值修改操作
工具类型
Required:必填
Readonly:只读
extends: 约束
keyof:提取对象属性名、索引名类型
in :类型映射
typeof : 提取变量类型
interface PersonItf{name:string;age?:number;
}// interface PersonItf1{
// name:string;
// age:number;
// }// 重复了// Required:必填
type PersonItf1 = Required<PersonItf>// Readonly:只读
type PersonItf2 = Readonly<PersonItf>// extends: 约束
type TypeFn<P> = P extends string | number ?P[]:P;
let a1:TypeFn<string> = ["111"]; //a1类型:string[]
let a2:TypeFn<boolean> = true; //a1类型:string[]// infer:类型推断
type TypeFn1<T> = T extends {name:infer N;age:infer A} ?[N,A]:[T]
let a3:TypeFn1<{name:string,age:number}> = ["",2]
let a4:TypeFn1<boolean> = [false]// keyof:提取对象属性名、索引名类型
interface ObjItf{name:string;age:number;// [idx:number]:number;[key:string]:string | number;
}type TypeKeyof = keyof ObjItf //"name" | "age" | string | numberlet a1:TypeKeyof="name"
a1=2
a1=""// in :类型映射
type numAndStr = number | stringtype ObjType1 = {[key in numAndStr]:numAndStr}
let ob1:ObjType1 = {name:"",1:2
}// keyof in 组合使用 "name" | "age" | string | number
type Required<T> = {[P in keyof T]-?:T[P]}
type ItfType = Required<ObjItf>// typeof : 提取变量类型
let a2 =1;
type TypeA2 = typeof a2let obj2 = {name:"",age:20
}type ObjType2 = typeof obj2;let obj3:ObjType2 = {name:"",age:10
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
