1. typescript是微软开发的一款新的编程语言。
2. typescript是javascript的超集,它包含ES7/ES6/ES5,遵循最新的ES规范。它扩展了javascript语法。
它弥补了javascript在类型检查方面的弱点。它在编译阶段提供了丰富的类型检查的语法提示。
1. 越来越多的项目基于ts开发,如vue3, react16, VSCode
2. ts提供的编译阶段的类型检查,可以避免很多线上错误。
1. 全局安装
cnpm install -g typescript
生成一个全局命令: tsc
可以直接使用
tsc xxxx.ts
将ts文件转为同名的js文件。
但是每次都这么使用,会非常繁琐。可以在package.json中,配置脚本命令。
scripts: { "build": "tsc", "dev": "tsc --watch" }
类似webpack,脚本命令需要对应的配置文件。
tsc --init // 生成一个tsconfig.json的配置文件
let myname: string = ‘lyra‘; let age: number = 18; let married: boolean = false;
1)指定某一类型的数据
2)长度不定
let arr:Array<number> = [1,2,3]; let hobbies:string[] = [‘football‘, ‘reading‘];
1)长度和类型都固定
2)每一项类型都可不同
let info:[string, number, boolean] = [‘lyra‘, 18, false];
enum Gender{ BOY, GIRL } /** * 相当于Gender[0] = "BOY"; Gender["BOY"] = 0; * Gender[1] = "GIRL"; Gender["GIRL"] = 1; */ let gender1:Gender = Gender.BOY; // 0 let gender2:Gender = Gender.GIRL; // 1
const enum Color { RED=1,// 指定其实数值 BLUE, YELLOW } // 被编译成console.log(1 /* RED */, 2 /* BLUE */, 3 /* YELLOW */) console.log(Color.RED, Color.BLUE, Color.YELLOW); // 1 2 3
当数据可能有多种类型时
let temp1:number|string = ‘2‘; let temp2:number|string = 2; // 可能是空 let node:HTMLElement|null = document.getElementById(‘root‘); // !非空断言操作符:指定其不可能为空 node!.style.color = ‘red‘;
可以是任意类型; 等于不指定类型
let temp:any = [1,23]; let temp2:any = ‘str‘;
let a:number; // StrictNullChecks:false a = undefined; a = null;
但是StrictNullChecks默认为true,此时需要
let a:number|null|undefined;
非任何类型;一般指不返回任何值。
function fn(name:string):void {// 指定返回值是void // 当StrictNullChecks=true时 return undefined; //或者不返回, null会报错 // 如果想使得return null也可以,则需要设置当StrictNullChecks=false }
1)永远不会有返回值
2)或者永远访问不到
1. 比如一个一直执行的任务:如轮询任务
function loop():never { // 用于一直运行不停止的功能:如轮询等 while(true) { // 死循环 } }
2. 抛出异常
function err():never { throw new Error(‘err‘); }
3. 永远访问不到
function test(x:number|string) { if(typeof x === ‘number‘) { console.log(x); // number } else if(typeof x === ‘string‘) { console.log(x); // string } else { console.log(x); //此时x是never类型 } }
当不指定数据类型,但是初始化时赋值具体的值时,ts会默认其为初始值的类型。
let a1 = 10; // ts默认a1是number类型 a1 = ‘str‘; // 报错!
想要上面的不报错,可以:
let a2; // 此时默认a2:any a2 = 10; a2 = ‘str‘;
或者
let a3: any = 10; a3 = ‘str‘;
let x: string= ‘somethings‘; x.toLowerCase() // 内部自动打包成 new String(x).toLowerCase()
手动指定不确定类型的数据为某种类型
// 强制告诉ts,指定数据的类型 let s:number|string|null|undefined; // 通常变量不能在赋值前使用;因为s有undefined类型,不会报错 (s as string).length; //使得遍历可以使用特定类型的方法
将具体的值组合在一起,构成字面量类型。该类型从指定的数据中取值。
比枚举类型更自由。
let n:1|2|‘d‘|true|[1,2]; //n可以是1,2,‘d‘,true,[1,2]中的任意一个值
// 指定参数类型为string,返回值类型string function fn(name: string):string { return ‘hello‘ + name; }
// 当不指定参数类型时,会暗示类型为any类型。此时会给出提示,希望可以指定具体的类型。 // 会出现该提示是因为tsconfig.json中默认noImplicitAny: true // 如果修改noImplicitAny: false, 该提示会不再出现 function foo(name) {//Parameter ‘name‘ implicitly has an ‘any‘ type }
// 定义一个类型,用来约束函数表达式 type barType = (x:string) => void; // x是形参 let bar:barType = function(name: string):void { }
当有些参数可有可无时
// age参数可有可无 function print(name: string, age?: number):void { } print(‘lyra‘); print(‘lyra‘, 18);
function ajax(url: string, method:string=‘GET‘):void { console.log(url, method); //‘/user‘ ‘GET } ajax(‘/user‘)
当传参的数量不固定时,使用剩余参数
function sum(...numbers:Array<number>):void { console.log(numbers) } sum(1,2,4); //[1,2,4] sum(1,2,3,4); // [1,2,3,4]
const obj = {name: ‘a‘, age: 10}; function attr(val: string):void; // 函数定义;后面只能跟函数定义或者函数实现 function attr(val: number):void; // 函数定义 function attr(val: any):void { //函数实现 if(typeof val === ‘string‘) { obj.name = val; } else if(typeof val === ‘number‘) { obj.age = val; } } attr(‘lyra‘); attr(20); attr(true); //!报错! 根据上面,参数受限于函数定义的参数类型
class Person { // strictPropertyInitialization: true // 默认是true,即必须给属性赋初值 // 初始化有两种方式:1)直接赋值 2)在constructor中赋值 name:string = ‘lyra‘; //实例属性-直接赋值 age: number; constructor(age:number) { this.age = age; //实例属性-构造函数中接受外部传入的参数赋值 } getName() { // 原型链上的方法 return this.name; } }
class User { myname:string; constructor(name:string) { this.myname = name; } get name() { //name是原型链上的属性 return this.myname; } set name(val:string) { this.myname = val; } } const user = new User(‘lyra‘); console.log(user.name); // lyra user.name = ‘lyraLee‘; console.log(user.name); // lyraLee console.log(user.hasOwnProperty(‘name‘)); // fasle // 获取实例的原型对象使用Object.getPrototypeOf() // __proto__是内部的私有属性,拒绝使用 console.log(Object.getPrototypeOf(user).hasOwnProperty(‘name‘)); //true
class Mother { public name:string; protected age:number = 18; private money:number = 500; constructor(name: string) { this.name = name; } getName() { return this.name; // ?自身可访问public属性 } getAge() { return this.age; // ?自身可访问protected属性 } getMoney() { return this.money; // ?自身可访问private属性 } } class Child extends Mother{ getName() { return this.name; // ?子类可访问public属性 } getAge() { return this.age; // ?子类可访问protected属性 } getMoney() { return this.money; //?子类不能访问private属性 } } const mother1 = new Mother(‘Lucy‘); console.log(mother1.name); // Lucy ?外部可访问public属性 console.log(mother1.age); // ? 外部不能访问protected属性 console.log(mother1.money); // ? 外部不能访问money属性
class Animal{ readonly age:number; constructor(age:number) { this.age = age; //只读属性,可以进行初始化 } } const dog = new Animal(10); console.log(dog.age); //10 dog.age = 20; //?因为是只读属性
class Book{ // 相当于Book.author = ‘lyra‘; static author = ‘lyra‘; // 相当于Book.getAuthor() {} static getAuthor() { // this取方法运行时所在的对象,此时this是类本身 console.log(this.author); // lyra } } Book.getAuthor() // ‘lyra‘
只能被继承,不能别实例化(不能使用new命令);
封装了一些公共属性和方法,供子类调用;还可以设置公共方法必须被重写
abstract class Parent{ public name:string = ‘parent‘; public giveMoney() { throw new Error(‘该方法必须被重写‘) } }
原文:https://www.cnblogs.com/lyraLee/p/12142438.html