typescript

1、typescript 安装 编译

在使用npm命令之前必须安装 nodejs
//
安装 npm install -g typescript
cnpm install -g typescript
yarn global add typescript

//运行
tsc helloworld.ts
//注意:如果电脑上面没有安装过cnpm,先安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

//如果使用yarn安装
npm install -g yarn 或者 cnpm install -g yarn

//查看typescript版本
tsc -v

//typescript开发工具vscode自动编译ts文件
步骤一:创建 tsconfig.json 文件, tsc --init 生成配置文件
步骤二:打开 tsconfig.json 文件,找到 outDir配置为: outDir:'./js'
步骤三:在 vscode开发工具中,点击终端--点击运行任务---点击tsc监视-tsconfig.json
然后写完代码就可以自动生成js文件了。

 2、typescript 数据类型

布尔类型 (boolean) true false
var flag:boolean = true;
如果这样子写: flag = 'hello';//会报错,因为写法错误

数字类型 (number)
var a:number = 123;
如果想把a赋值其他类型就会报错哦

字符串类型(string)
var str:string = 'hello';

数组类型(array) ts中定义数组有两种方式
第一种:
let arr1:number[] = [1,2,3,4]
let arr2:string[] = ["js","golang"]
第二种:
let arr3:Array<number> = [1,2,3]
第三种:
var arrs:any[] = [1,'hello',false];

元组类型(tuple) 属于数组的一种,指定数组里面值的类型
let arr:[string,number,boolean] = ['hello',2,true];

枚举类型(enum)
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
}
pay_staus 0 未支付, 1 支付 , 2交易成功
flag 1表示true -1表示false

enum Flag{success=1,error=-1}
var f:Flag = Flag.success
console.log(f);//1
eg:
enum Color{red,blue,orange=5,green}
var c:Color = Color.blue;
var d:Color = Color.green;
console.log(d);//6 这个值是基于 orange的基础上+1来的
console.log(c);//输出1,如果没有赋值的话打印出对应值的索引值

任意类型 (any)
var num:any = 123;
num = 'str';
num = true;
用处:
var oBox:any = document.getElementById('box');
oBox.style.color = 'red';


null 和 undefined 其他(never类型)数据类型的子类型
var num:number;
console.log(num);//变量定义未赋值,是undefined,报错
var num:undefined;
console.log(num);//输出 undefined ;正确
var num:number|undefined;
num = 123;
console.log(num);//正确
var num:null;
num = 123;//会报错
num = null;//不报错
一个元素可能是 number类型可能是null可能是undefined
var num:number|null|undefined;
num = 123;//不会报错

void类型:typescript中的void表示没有任何类型,一般用于定义方法的时候方法没有返回值。
//es5
function run(){
console.log('run')
}
run();
//表示方法没有返回任何类型
function run():void{
console.log('run')
}
//如果有返回值
function run():number{
return 123
}

never 类型:是其他类型(包括null 和 undefined)的子类型,代表从不会出现的值
var a:undefined;
a = undefined;

var b = null;
b = null;

var a:never;
a = 123;//报错,错误写法
a = (()=>{
throw new Error('错误')
})()

3、typescript中的函数

函数的定义:
//函数声明法 es5
function run(){
return 'run';
}
//匿名函数 es5
var run2 = function(){
return 'run2';
}
//ts中定义函数的方法
函数声明法:
function run():string{
return 'hello';
}
匿名函数
var run2 = function():number{
return 123;
}

//ts 中定义方法传参
function getInfo(name:string,age:number):string{
return `${name}---${age}`;
}
alert(getInfo('sunny',20);

var getInfo = function(name:string,age:number):string{
return `${name}---${age}`;//模板字符串
}
//没有返回值的方法
function runs:void(){
console.log('runs')
}
runs();

//方法可选参数
es5里面方法的实参和行参可以不一样,但是 ts 中必须一样,如果不一样就需要配置可选参数
function getInfo(name:string,age?:number):string{//注意在参数前面加上 问号 ?
if(age){
return `${name}----${age}`
}else{
return `${name}----年龄保密`
}
}
console.log(getInfo('hello'));
//注意:可选参数必须配置到参数的最后面

//默认参数
es5里面没法设置默认参数,es6 和 ts中可以设置默认参数

function getInfo(name:string,age:number=20):string{
   if(age){
return `${name}----${age}`
}else{
return `${name}----年龄保密`
}
}
alert(getInfo('hello'));//hello----20

//剩余参数
function sum(a:number,b:number,c:number,d:number):number{
return a+b+c+d;
}
sum(1,2,3,4);
三点运算符,接受行参传过来的值:
function sum(...result:number[]):number{
var sums = 0;
for(var i=0;i<result.length;i++){
sums+=result[i];
}
return sums;
}
sum(1,2,3,4);
另外一种写法:
function sum(a:number,b:number,...result:number[]):number{
var sums = =a+b;
}
sum(1,2,3,4,5,6);

//函数重载
Java中方法的重载,重载指的是两个或者两个以上同名函数,但他们的参数不一样,
这时会出现函数重载的情况
typescript中的重载,通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
ts为了兼容 es5 以及 es6重载的写法和Java中的区别。

//es5中出现同名方法,下面的会替换上面的方法
function css(config){
}
function css(config,value){
}
//ts 中支持方法的重载
function getInfo(name:string):string;
function getInfo(age:number):number;
function getInfo(str:any):any{
if(typeof str==='string'){
return 'i am'+str;
}else{
return 'age'+str;
}
}
alert(getInfo('hello'));//i am hello.正确写法
alert(getInfo(20));//age 20. 正确写法
alert(getInfo(true));//错误写法

//箭头函数 es6
setTimeout(function(){

},1000)
setTimeout(()=>{},1000);//this 指向上下文

4、typescript里面的类继承

//es5 里面的类
//1.最简单的类
function Person(){
this.name = 'sunny';
this.age = 18;
}
var p = new Person();
alert(p.name);
//2.构造函数和原型链增加方法
function Person(){
this.name = 'sunny';
this.age = 18;
this.run = function(){
alert(this.name+'running');
}
}
//原型链上面的属性会被多个实例共享,构造函数不会
Person.prototype.sex = 'man';
Person.prototype.work = function(){
alert(this.name+'working');
}
var p = new Person();
p.run();
p.work();
//3.类里面的静态方法
function Person(){
this.name = 'sunny';//属性
this.age = 20;
this.run = function(){ //实例方法
console.log(this.name+'running');
}
}
Person.getInfo = function(){
console.log('静态方法');
}
var p = new Person();
Person.getInfo();//调用静态方法
//4.es5里面的继承
function Person(){
this.name = 'sunny';
this.age = 20;
this.run = function(){
console.log(this.name+'running');
}
}
Person.prototype.sex = 'man';
Person.prototype.work = function(){
console.log(this.name+'working');
}
//web类继承 Person类(原型链+对象冒充的组合继承模式)
function Web(){
Person.call(this);//对象冒充实现继承,Web继承Person
}
var w = new Web();
w.run();//对象冒充可以继承构造函数里面的属性和方法
w.work();//会报错,work is not a function。但是没法继承原型链上面的属性和方法

//5.原型链实现继承
function Web(){

}
Web.prototype = new Person();//原型链实现继承
var w = new Web();
w.run();//sunny running
w.work();//sunny working
原型链实现继承好处:可以继承构造函数里面的属性和方法,也可以继承原型链上面的属性和方法。
//6.原型链实现继承出现的问题:
function Person(name,age){
this.name = name;
this.age = age;
this.run = function(){
console.log(this.name+'running');
}
}
Person.prototype.sex='man';
function Web(name,age){

}
Web.prototype = new Person();
var w = new Web('eve',20);
w.run();//undefined running。实例化子类的时候没法给父类传参

//7.原型链+构造函数的组合继承模式
function Web(name,age){
Person.call(this,name,age);//对象冒充继承 实例化子类可以给父类传参
}
//8.原型链+对象冒充的另外一种方式
将 Web.prototype = new Person() 改成 Person.prototype 。

//////// typescript 中定义类
1.ts中类的定义
class Person{
name:string;//属性
constructor(name:string){//构造函数 实例化类的时候触发的方法
this.name = name;
}
run():void{
console.log(this.name);
}
getName():string{
return this.name;
}
setName(name:string):void{
this.name = name;
}
}
//实例化
var p = new Person('sunny');
p.run();
console.log(p.getName());

2.ts中实现继承 extends , super
class Person{
name:string;
constructor(name:string){
this.name = name;
}
run():string{
return `${this.name}在运动`
}
}
var p = new Person('王五');
console.log(p.run());//王五在运动

class Web extends Person{
constructor(name:string){
super(name);//初始化父类的构造函数
}
work(){
console.log(`${this.name}在工作`)
}
}
var w = new Web('李四');
console.log(w.run());//李四在运动
console.log(w.work());//李四在工作

问题:ts中继承的探讨 父类的方法和子类方法一致

3.类里面的修饰符
typescript 里面定义属性的时候提供了三种修饰符:
public , 在类里面,子类,类外面都可以访问
protected,在类里面,子类里面可以访问,在类外部没法访问
private 在类里面可以访问,子类,类外部都没法访问
属性如果不加修饰符默认就是public。

4.静态属性 静态方法
class Person{
public name:string;
public age:number = 20;
static sex = 'man';
constructor(name){
this.name = name;
}
run(){
console.log(`${this.name}在运动`);
}
static print(){
console.log('print 方法');//静态方法, 没法直接调用类里面的属性
//除非 定义属性为静态属性才可
console.log(Person.sex);//man
//调用其他属性的话会报 undefined。
}
}
var p = new Person('sunny');
p.run();
Person.print();
console.log(Person.sex);//man

5.多态:父类定义一个方法不去实现,让继承他的子类去实现,每一个子类有不同的表现
多态属于继承
class Animal{
name:string;
constructor(name:string){
this.name = name;
}
eat(){
console.log('吃的方法');//具体吃什么不知道。具体吃什么是由他的子类去实现,每一个子类的表现都不一样
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name +'吃肉';
}
}
class Cat extends Animal{
constructor(name:string){
super(name);
}
eat(){
return this.name+'吃老鼠';
}
}

6.抽象方法
typescript中的抽象类,他是提供其他类继承的基类,不能直接被实例化。
用 abstract 关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
abstract 抽象方法只能放在抽象类里面
抽象类和抽象方法用来定义标准。标准是 Animal 这个类要求他的子类必须包含 eat方法。

abstract class Animal{
public name:string;
constructor(name:string){
this.name = name;
}
abstract eat():any;
}
var a = new Animal();//错误写法,没法直接实例化

class Dog extends Animal{
//抽象类的子类必须实现抽象类里面的抽象方法
constructor(name:any){
super(name)
}
eat(){
console.log(name+'吃粮食')
}
}
var d = new Dog('小花花');
d.eat();//小花花吃粮食

5.typescript 中的接口

接口作用:
在面向对象的编程中,接口是一种规范的定义,他定义了行为和动作的规范。


1.属性接口 (对json的约束)
function printLabel(label:string):void{

}
//对象
function printLabel(labelInfo:{label:string}):void{

}
printLabel({name:'sunny'});//错误写法
printLabel({label:'sunny'});//正确写法
//批量方法传入参数进行约束
interface 定义接口
//就是传入对象的约束,属性接口
interface FullName{
firstNmae:string;//分号结束
secondName:string;
}
function printName(name:FullName){
//必须传入对象 firstName secodName
console.log(name.firstName+'------'+name.secondName);
}
function printInfo(info:FullName){
console.log(info.firstName+'----'+info.secondName);
}
var obj = {//传入的参数必须包含 firstName 和 secondName
age:20,
firstName:'s',
secondName:'u'
};
var info = {
firstName:'e',
secondName:'v'
};
printName(obj);
printInfo(info);


2.接口 可选属性
//传入的参数顺序可以不一样
interface FullName{
firstName:string;
secondName?:string;//这样子就可以选择传参还是不传入参数
}
function getName(name:FullName){
}
getName({
firstName:'s'
})

例子:(jQuery)原生js封装Ajax
interface Config{
type:string;
url:string;
data?:string;
dataType:string
}
function ajax(config:Config){
var xhr = new XMLHttpRequest();
xhr.open(config.type,config.url,true);
xhr.send(config.data);
xhr.onreadystatechange = function(){
if(xhr.readyState==4&&xhr.status==200){
console.log('success')
if(config.dataType==='json'){
return JSON.parse(xhr.responseText);
}else{
return xhr.responseText;
}
}
}
}
ajax({
type:'get',
url:'xxx',
dataType:'json',
data:'name=sunny'
})

3.函数类型接口:对方法传入的参数以及返回值进行约束
//加密的函数类型接口
interface encrypt{
(key:string,value:string):string;
}
var md5:encrypt = function(key:string,value:string):string{
//模拟操作
return key+value;
}
//用法
console.log(md5('name','sunny'));

4.可索引接口,对数组,对象的约束(不常用)
//定义数组的方式
var arr:number[] = [1,2,3];
var arr1:Array<string> = ['11','22'];

interface UserArr {
[index:number]:string
}
var arr:UserArr = ['aa','bb'];
console.log(arr[0]);//输出aa

//可索引接口 对对象的约束
interface UsereObj{
[index:string]:string
}
var arr1:UserObj = {name:'sunny',age:20};

5.类类型接口: 对类的约束 和抽象类相似 (常用)
interface Aniaml{
name:string;
eat(str:string):void;
}
class Dog implements Animal{
name:string;
constructor(name:string){
this.name = name;
}
eat(){
console.log(this.name+'吃粮食');
}
}
var d = new Dog('小黑');
d.eat();//小黑吃粮食

6.接口扩展,接口可以继承接口
interface Animal{
eat():void;
}
interface Person extends Animal{
work():void;
}
class Programmer{
public name:string;
constructor(name:string){
this.name = name;
}
coding(code:string){
console.log(this.name+code)
}
}

class Web extends Programmer implements Person{
constructor(name:string){
super(name)
}
eat(){
console.log(this.name+'喜欢吃馒头')
}
work(){
console.log(this.name+'写代码')
}
}
var w = new Web('sunny');
w.work();//sunny 写代码
w.coing('ts代码');//sunny 写ts代码

 6.typescript 中的泛型

泛型解决 类 接口 方法的复用性,以及对不特定数据类型的支持

//同时返回 string 类型和 number 类型
//any 放弃了类型检查,传入什么,返回什么。

function getData<T>(value:T):T{ //T表示泛型,具体什么类型是调用这个方法的时候决定的
return value;
}
getData<number>(123);
getData<number>('123');//错误写法

//泛型类,比如有个最小堆算法,需要同时支持返回数字和字符串两种类型,通过类的泛型来实现
clas MinClass{
public list:number[] = [];
add(num:number){
this.list.push(num);
}
min():number{
var minNum = this.list[0];
for(var i=0;i<this.list.length;i++){
if(minNum>this.list[i]){
minNum = this.list[i]
}
}
return minNum;
}
}
var m = new MinClass();
m.add(3);

//定义类的泛型
class MinClass<T>{
public list:T[] = [];
add(value:T):void{
this.list.push(value);
}
min():T{
var minNum = this.list[0];
for(var i=0;i<this.list.length;i++){
if(minNum>this.list[i]){
minNum = this.list[i]
}
}
return minNum;
}
}
var m1 = new MinClass<number>();//实例化类,并且指定了类的T代表的类型是number
m1.add(1);
m1.add(2);
m1.add(3);
console.log(m1.min());//1

//泛型接口
//这个是函数类型接口
interface ConfigFn(){
(value1:string,value2:string):string;
}
var setData:ConfigFn = function(value1:string,value2:string):string{
return value1+vlaue2;
}
setData('name','sunny');

//改造后
interface ConfigFn{ //换种写法: interface ConfigFn<T>{}
<T>(value:T):T;
}
var getData:ConfigFn = function<T>(value:T):T{
return value;
}
getData<string>('sunny');

//换种写法:
function getData<T>(value:T):T{};
var myGetData:ConfigFn<string>=getData;
myGetData('20');

例子://定义一个user类这个类的作用是映射数据库字段,然后定义一个mysqldb的类,这个类用于操作
数据库
class User{
username:string | undefined;
password:string | undefined
}
class MysqlDb<T>{
add(user:T):boolean{
console.log(user,'user');//zhangsan 123456
return true;
}
}
var u = new User();
u.username = 'zhangsan';
u.password = '123456';
var Db = new MysqlDb<User>();
Db.add(u);

 7.typescript 类型,接口,类,泛型综合使用-typescript封装统一操作mysql mongodb mssql底层库

//定义一个操作封装数据库的库支持mysql
//约束统一的规范,以及代码重用
interface DBI<>T{
add(info:T):boolean;
update(info:T,id:number):boolean;
delete(id:number):boolean;
get(id:number):any[]
}
//定义一个操作mysqo数据库的类,要实现泛型接口,这个类也应该是一个泛型类
class MysqlDb<T> implements DBI<T>{

}
//定义一个操作mysql的数据库的类
calss
原文地址:https://www.cnblogs.com/sunnyeve/p/13220631.html