1.安装ts环境
1.cnpm i typescript -g //全局安装ts
2.cnpm i -g ts-node //全局安装ts-node
3.tsc --init //生成 tsconfig.js 配置文件
//编写ts代码
const a: string = "hello";
console.log(a);
4.tsc index.ts //编译 ts 为 js 在控制台(终端)输入命令
5.ts-node index.ts//直接编译ts在控制台输出
6.tsc --watch index.ts//监听每次文件变动 ts 帮我们**自动编译成 js**
2.数据类型
//string number boolean symbol undifine null
const flag:number=2
const flag1:string='www'
const flag2:boolean=false
const flag3 = Symbol("hello");
const flag4:undefined=undefined
const flag5:null = null
3.函数void,never
//eg:number
function fn(num1:number,num2:number){
console.log(num1+num2)
}
fn(1,2)//为number类型
//void表示没有返回值得函数
function fn(num1:number,num2:number):void{
console.log(num1+num2)
}
//never表示永远没有返回值得函数
function fn(num1:number,num2:number):never{
console.log(num1+num2)
}
fn(1,2)
4.数组
//申明:2种方式都行
let arr1:number[] =[1,2,3] //只能push number类型
let arr2:Array<number> = [1,2,3]
let arrStr:string[]=["1","2","3"]//只能push string类型
//数字和字符串都有时申明
let arr:(string|number)[] = ["刘备",2] //可以push number或string类型
5.元组(特殊得数组)
let arr:[string,number][] = [
["张三",3],
["里斯",4],
["王五",5]
]
let arrObj:{name:string,value:number}[] = [
{name:"张三",value:3},
{name:"里斯",value:4},
{name:"王五",value:5}
]
6.any类型
//any类型
//1.引发数据类型安全问题
//2.any代表开发者想要绕开类型检测
//3.实在写不出类型了可用
let str:any = "123"
str = 123
7.不确定类型和值 unknown (少用)
unknown类型只能被赋值给 any 类型和 unknown 类型
let un:unknown;
let num:unknown = un
let num1:any = un
8.字面量(根据值来判断类型)
let mynum:123 = 123
let mybool:true = true
9.返回值类型
//es5 写法
//函数后面的number表示这个函数得返回值就是number类型
function fn(num1:number,num2:number):number{
return num1+num2
}
console.log(fn(1,2))
//es6
const fn1 = (num1:number,num2:number):number =>{
return num1+num2
}
console.log(fn1(1,2))
10.类型断言
手动告诉 ts 就按照你断言的那个类型通过编译(有时候可以帮助你解决很多编译报错)
//断言 someValue 为string类型
// 1.尖括号 语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// 2.as 语法
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
非空断言
let flag: null | undefined | string;
flag!.toString(); // ok
flag.toString(); // error
11.剩余参数
//剩余参数 在 arg 里面
let fn = (num1:number,...arg:number[])=>{
return arg.reduce((pre,next)=>{
return pre + next
},num1)
}
console.log(fn(1,2,3,5))
12.this
function fn(this:Window,str:string){
//1.在这里指明this指向window
//2.this:Window 不会占用第一个参数的位置 还可以fn("你")调用
console.log(this)
}
window.fn = fn;
window.fn("你")
13.类
class Person {
name:string//需要告诉要申明的属性的类型,不然编译报错
constructor (name:string){
this.name= name
}
getName():void{//没有返回值
console.log(this.name)
}
}
let p = new Person("刘备")
p.getName()
14.继承
class Person {
name:string
constructor (name:string){
this.name= name
}
getName():void{
console.log(this.name)
}
}
class Man extends Person {
six:boolean
constructor (name:string,six:boolean){
//这里super继承了父类的this.name 所以不需要申明类型
super(name)
this.six = six
}
getInfo ():void {
console.log(`${this.name}是个${this.six?'男':'女'}`)
}
}
let m = new Man("关羽",true)
m.getInfo()
15.ts面向对象修饰符
public,protected,private
//1.**public** 类里面 子类 其它任何地方外边都可以访问
//2.**protected** 类里面 子类 都可以访问,其它任何地方不能访问
//3.**private** 类里面可以访问,子类和其它任何地方都不可以访问
class Parent {
public name: string;
protected age: number;
private car: number;
constructor(name: string, age: number, car: number) {
//构造函数
this.name = name;
this.age = age;
this.car = car;
}
getName(): string {
return this.name;
}
setName(name: string): void {
this.name = name;
}
}
class Child extends Parent {
constructor(name: string, age: number, car: number) {
super(name, age, car);
}
desc() {
console.log(`${this.name} ${this.age} ${this.car}`); //car访问不到 会报错
}
}
let child = new Child("hello", 10, 1000);
console.log(child.name);
console.log(child.age); //age访问不到 会报错
console.log(child.car); //car访问不到 会报错
16.静态属性和静态方法
class Parent {
static mainName = "Parent";
static getmainName() {
console.log(this); //注意静态方法里面的this指向的是类本身 而不是类的实例对象 所以静态方法里面只能访问类的静态属性和方法
return this.mainName;
}
public name: string;
constructor(name: string) {
//构造函数
this.name = name;
}
}
console.log(Parent.mainName);
console.log(Parent.getmainName());
17.接口 interface
//告知obj里面字段的类型
interface Iobj {
name:string,
age:number
}
function fn(obj:Iobj){
console.log(`姓名${obj.name}年龄为${obj.age}`)
}
fn({name:"张三",age:12})
18.可缺省属性与任意属性
age?:number[propName:string]:any
//
interface Iobj {
name:string,
age?:number// ?表示age可传可不传 可缺省属性
[propName:string]:any //不清楚后面还有申明属性传入可这样写 任意属性
}
function fn(obj:Iobj){
console.log(`姓名${obj.name}年龄为${obj.age}`)
}
fn({name:"张三",gender:"男"})
19.泛型 T
function fn(num:number,str:string):string[]{
let arr = []
for (let index = 0; index < num; index++) {
arr.push(str)
}
return arr
}
console.log(fn(3,'你好世界'))
//泛型 使用 把string换成T
//不确定后面参数 str的类型 则可以使用泛型
//输出的值的类型会受输入的值的类型影响
function fn1<T>(num:number,str:T):T[]{
let arr:T[] = []
for (let index = 0; index < num; index++) {
arr.push(str)
}
return arr
}
console.log(fn1(3,true))
20.泛型多个参数
//T U R 可随便用其他字符定义
//以一个数组的形式返回出去
//多个参数数据类型会影响到返回的数据类型
//2个参数
function fn<T,U>(arg1:T,arg2:U):(U | T)[]{
let arr:(T | U)[] = [arg1,arg2]
return arr
}
console.log(fn(true,"你好世界"))
//3个参数
function fn1<T,U,R>(arg1:T,arg2:U,arg3:R):(U | T | R)[]{
let arr:(T | U | R)[] = [arg1,arg2,arg3]
return arr
}
console.log(fn1(true,"你好世界",123))
21.Enum 类型 枚举
使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错误码等
// 普通枚举 初始值默认为 0 其余的成员会会按顺序自动增长 可以理解为数组下标
enum Color {
RED,
PINK,
BLUE,
}
const pink: Color = Color.PINK;
console.log(pink); // 1
// 设置初始值
enum Color {
RED = 10,
PINK,
BLUE,
}
const pink: Color = Color.PINK;
console.log(pink); // 11
// 字符串枚举 每个都需要声明
enum Color {
RED = "红色",
PINK = "粉色",
BLUE = "蓝色",
}
const pink: Color = Color.PINK;
console.log(pink); // 粉色
// 常量枚举 它是使用 const 关键字修饰的枚举,常量枚举与普通枚举的区别是,整个枚举会在编译阶段被删除 我们可以看下编译之后的效果
const enum Color {
RED,
PINK,
BLUE,
}
const color: Color[] = [Color.RED, Color.PINK, Color.BLUE];
//编译之后的js如下:
var color = [0 /* RED */, 1 /* PINK */, 2 /* BLUE */];
// 可以看到我们的枚举并没有被编译成js代码 只是把color这个数组变量编译出来了