/* boolean */
var b:boolean = true
/* number */
var a:number = 123
/* string */
var str:string = "this is str"
/* array */
var arr1:number[] = [1,2,3]
var arr2:string[] = ["java","C#"]
var arr3:Array<number> = [1,2,3]
var arr4:Array<string> = ["java","C#"]
/* tuple元组类型(数组的一种) */
var tup:[string,number,boolean] = ["ts",123,true]
/* enum 枚举*/
enum flag{success = 1,error = 2}
var f:flag=flag.success /* 1 */
/* any 任意类型 */
var num:any = 123;
num = true;
/* null 和 undefined 其他(never类型)的子类型 */
var num2:number|undefined
var num3:number|null
var num4:number|null|undefined
/* void 用于定义方法没有任何类型,一般用于定义方法没有返回值*/
function run():void
{
console.log("run")
}
/* never:其他类型(包括null和undefined), 表示从不会出现的值(声明never的变量只允许被never类型所赋值) */
var u:undefined
u = undefined
var c:null
c = null
/* --------------------------------函数定义---------------------------------------- */
/* 函数声明法 */
function fun1():string
{
return "fun1"
}
/* 匿名函数法 */
var fun2=function():string
{
return "fun2"
}
/* 定义方法传参 */
function getInfo(name:string,age:number):string
{
return `${name} -- ${age}`
}
var say = function(name:string):string
{
return `say ${name}`
}
/* 无返回值 */
function run1():void{
console.log("run1")
}
/* 可选参数 */
/* 注意:可选参数必须配置在参数的最后面 */
function getInfo2(name:string,age?:number):string /* 调用时age参数可选 */
{
if(age){return 'age ${age}'}
else{return "age secret"}
}
/* 默认参数 */
function getInfo3(name:string,age:number = 20):string
{
return `${name}-age:${age}`
}
getInfo3("jack") /* jack-age:20 */
getInfo3("jack",30) /* jack-age:30 */
/* 剩余参数 */
function sum(...result:number[]):number{
var sum:number = 0;
for(var i = 0; i<result.length;i++)
{
sum+=result[i]
}
return sum
}
/* 函数重载 */
function fun3(name:string):string{
return 'name'
}
function fun4(age:number):number{
return 100
}
/* 箭头函数 */
setTimeout(()=>{alert("hi")},1000)
/* es5中的继承 */
function Person(name,age){
this.name = name;
this.age = age;
this.run = function() // 实例方法
{
alert(this.name+"在run")
}
}
Person.prototype.work = function()
{
alert(this.name+"在work")
}
//web 类继承Person
/* 通过对象冒充实现继承 */
function Web(name,age)
{
Person.call(this)
}
var w = new Web()
w.run() //对象冒充可以继承构造函数中的属性和方法
w.work()//报错,无法调取work(), 因为对象冒充无法继承原型链上的属性和方法
/* 通过原型链实现继承 */
function Web2(name,age)
{
}
Web2.prototype = new Person() //既可以继承构造函数里的属性和方法,也可也继承原型链中的属性和方法
var w2 = new Web2("jack",11) //但是实例化时无法给父类传参
w2.run() //undefined在run
/* 原型链和对象冒充组合继承 */
function Web3(name,age)
{
Person.call(this,name,age)
}
Web3.prototype = new Person() //或者写成 Web3.prototype = Person.prototype
var w3 = new Web3("jack",11)
w3.run() //jack在run
w3.work() //jack在work
/* TS中类的定义 */
class Person
{
name:string; //属性,前面省略public关键词
constructor(name:string)
{
this.name = name
}
run():void
{
alert(this.name)
}
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
}
var p = new Person("Jack")
p.run()
alert(p.getName())
p.setName("Lucy")
/* TS中实现继承 */
class Person2
{
name:string; //属性,前面省略public关键词
constructor(name:string)
{
this.name = name
}
run():void
{
alert(this.name)
}
}
class P extends Person2{
constructor(name:string)
{
super(name) //初始化父类构造函数
}
work(){
alert(`${this.name} is working`)
}
}
var pp = new P("mike")
pp.run()
pp.work()
/* 类里面的修饰符 */
public : 类里面和外面以及子类都可访问
protected:类里面和子类里可以访问,外部无法访问
private:类里可以访问,子类和外部都无法访问
属性不加修饰符, 默认表示public
/* 静态属性和静态方法 */
class Person3
{
name:string; //属性,前面省略public关键词
static age:number = 20
constructor(name:string)
{
this.name = name
}
run():void
{
alert(this.name)
}
static print() //静态方法,里面无法调用类里面的属性,比如name
{
alert("print!")
}
}
Person3.print() // 静态方法直接调用
var A = Person3.age
/* 多态:父类定以一个方法但不实现,让继承它的子类去实现,每一个子类有不同的表现 */
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 + "is 狗粮"
}
}
class Cat extends Animal
{
constructor(name:string)
{
super(name)
}
eat()
{
return this.name + "is 猫粮"
}
}
/* TS中的抽象类,它提供其他类继承的基类,不能直接被实例化
用abstract关键字定以抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
抽象方法只能放在抽象类里面
抽象类和抽象方法用来定义标准
*/
abstract class Car{
public name:string
constructor(name:string)
{
this.name = name
}
abstract drive():any
}
class Car1 extends Car{
constructor(name:string)
{
super(name)
}
drive():any{
console.log("Car1 drive")
}
}
/* TS中接口 */
/* 1.属性接口 */
//自定义方法传入参数对json进行约束
function print(labelInfo:{label:string}):void{
}
print({label:"123"})
//对批量方法传入参数进行约束
interface FullName{
firstName:string;
secondName:string;
}
function printName(name:FullName):void{
console.log(name.firstName+'--'+name.secondName)
}
printName({firstName:"Jack",secondName:"Ma"})
var obj = { //这种写法的话只需要obj包含了firstName和secondName即可
age:12,
firstName:"Jack",
secondName:"Ma"
}
printName(obj)
//接口:可选属性
interface FullName2{
firstName:string;
secondName?:string; //可选参数
}
function getName2(name:FullName2)
{
console.log(name.firstName)
}
getName2({firstName:"jack"}) //secondName是可选参数可不传
/* TS封装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')
{
console.log(JSON.parse(xhr.responseText))
}
else{
console.log(xhr.responseText)
}
}
}
}
/* 函数类型接口:对方法传入的参数以及返回值进行约束 */
//例:加密的函数类型接口
interface encript
{
(key:string,value:string):string
}
var md5:encript = function(key:string,value:string):string
{
return key+value
}
md5("name","Jack")
/* 可索引接口:数组、对象的约束(不常用) */
//数组约束
interface UserArr{
[index:number]:string
}
var arr:UserArr=['123','456'];
//对象约束
interface UserObj
{
[index:string]:string
}
var uobj:UserObj = {name:'20'}
//类类型接口:对类的约束 和 抽象类相似
interface Animal{
name:string;
eat(str:string):void;
}
class Dog2 implements Animal{
name:string;
constructor(name:string)
{
this.name = name
}
eat()
{
console.log(this.name +"is Dog2")
}
}
var d = new Dog("小黑")
d.eat()
//接口扩展:接口可以继承接口
interface Animal2{
eat():void
}
interface Person_2 extends Animal2{
work():void
}
class Programmer
{
public name:string
constructor(name:string)
{
this.name = name
}
coding(code:string)
{
console.log(code+"coding")
}
}
class Web_2 implements Person_2{
public name:string
constructor(name:string)
{
this.name = name
}
eat(){
console.log("this is eat")
}
work(){
console.log("this is work")
}
}
var w_2 = new Web_2("Jack")
class Web_3 extends Programmer implements Person_2{
constructor(name:string)
{
super(name)
}
eat(){
console.log("this is eat")
}
work(){
console.log("this is work")
}
}
var w_3 = new Web_3("Jack")
/* 泛型:可以解决类、接口和方法的复用性以及对不特定数据类型的支持 */
function getData<T>(value:T):T{
return value
}
getData<number>(123)
getData<string>("123")
/* 泛型类 */
//例:有一个最小堆算法,需要同时支持返回数字和字符串两种类型,通过泛型实现
class MinClass<T>
{
public list:T[] = []
add(value:T)
{
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 m = new MinClass<number>();
m.add(2);
m.add(3);
m.add(55);
alert(m.min())
/* 泛型接口 */
//写法1
interface ConfigFn
{
<T>(value:T):T;
}
var setData:ConfigFn = function<T>(value:T):T{
return value
}
setData<string>("123")
//写法2
interface ConfigFn2<T>
{
(value:T):T;
}
function setData2<T>(value:T):T
{
return value;
}
var mysetData:ConfigFn2<string> = setData2
mysetData('123')
/* 把类作为参数类型的泛型类 */
//例: 定义一个user的类,用来映射数据库字段,然后定义一个mysqlDb类用于操作数据库,然后把这个user类作为参数传入到MysqlDb中
class User{
username:string|undefined
password:string|undefined
}
class MysqlDb1<T>{
add(user:T):boolean{
return true
}
}
var u1 = new User();
u1.username = "Jack"
u1.password = "123456"
var Db = new MysqlDb1<User>();
Db.add(u1)
//定义一个操作数据库的库,支持Mysql,Mssql,MongoDb
interface DBI<T>
{
add(info:T):boolean;
update(info:T,id:number):boolean;
delete(id:number):boolean;
get(id:number):any[];
}
class MysqlDb <T> implements DBI<T>
{
add(info: T): boolean {
console.log(info)
return true
}
update(info: T, id: number): boolean {
throw new Error("Method not implemented.")
}
delete(id: number): boolean {
throw new Error("Method not implemented.")
}
get(id: number): any[] {
throw new Error("Method not implemented.")
}
}
class MsSqlDb<T> implements DBI<T>
{
add(info: any): boolean {
throw new Error("Method not implemented.")
}
update(info: any, id: number): boolean {
throw new Error("Method not implemented.")
}
delete(id: number): boolean {
throw new Error("Method not implemented.")
}
get(id: number): any[] {
throw new Error("Method not implemented.")
}
}
class User1
{
username:string|undefined;
password:string|undefined;
}
var uu = new User1();
uu.username = "Jack"
uu.password = "123456"
var oMysql = new MysqlDb<User1>() //类作为参数来约束传入的类型
oMysql.add(uu)
/* 模块 */
//例: 新建一个文件 db.ts 内容如下:
var dbUrl = "xxx"
function getData1():any[]{
return [{
title:'123123'
}]
}
function save(){
console.log("save")
}
export {dbUrl,getData1,save}
//export default getData1 默认导出
//其他模块调用 :
import {getData1 as get,save} from './db'
//import getData1 from './db' 默认导出的调用方法
get()
save()
/* TS命名空间 */
//命名空间与模块的区别:
//命名空间:内部模块,主要用于组织代码,避免命名冲突
//模块:ts的外部模块简称,侧重代码复用,一个模块李可能含有多个命名空间
namespace AA{
interface Animal{
name:string;
eat():void;
}
export var main = "qq"
}
namespace BB{
interface Animal{
name:string;
run():void;
}
export var main = "wechat"
}
export namespace CC{
interface Animal{
name:string;
run():void;
}
export var main = "dingding"
}
var m_main = AA.main
var m_main2 = BB.main
/* TS装饰器
是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为
通俗来讲就是装饰器是一个方法,可以注入到类,方法,属性参数上来扩展类,属性,方法,参数的功能
常见的装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器
装饰器的写法:普通装饰器(无法传参),装饰器工厂(可传参)
装饰器是最近几年js最大的成就之一,是ES7的标准特性之一 */
//1.类装饰器:类装饰器在类声明致歉被声明,类装饰器应用于类构造函数,可以用来监视修改或替换类定义
//普通装饰器
function logClass(params:any){
console.log(params)
//params 就是当前类
params.prototype.apiUrl = "xxx";
}
@logClass
class HttpClient{
constructor()
{
}
getData()
{
}
}
var http:any = new HttpClient();
console.log(http.apiUrl);
//装饰器工厂(可传参)
function logClass2(params:string)
{
return function(target:any){
console.log(target)
target.prototype.apiUrl = params;
}
}
@logClass2('http://www.baidu.com')
class HttpClient2{
constructor()
{
}
getData()
{
}
}
var http2:any = new HttpClient2();
console.log(http2.apiUrl)
//类装饰器 重载构造函数的例子:
/* 类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数,
如果类装饰器返回一个值,它会使用提供的构造函数类替换类的声明 */
function logClass3(target:any)
{
console.log(target)
return class extends target{
apiUrl:any = "我是修改后的url"
getData()
{
console.log(this.apiUrl)
}
}
}
@logClass3
class HttpClient3{
public apiUrl:string|undefined
constructor()
{
this.apiUrl = "我是构造函数里的url"
}
getData()
{
console.log(this.apiUrl)
}
}
var http3 = new HttpClient3()
/* 2.属性装饰器 */
/* 属性装饰器表达式会在运行时当作函数的被调用,传入下列2个参数:
a.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
b.成员的名字 */
function logProperty(params:any)
{
return function(target:any,attr:any)
{
console.log(target)
console.log(attr)
target.attr = params
}
}
class HttpClient4{
@logProperty("http://www.baidu.com")
public apiUrl:string|undefined
constructor()
{
this.apiUrl = "我是构造函数里的url"
}
getData()
{
console.log(this.apiUrl)
}
}
var http4 = new HttpClient4()
http4.getData()
/* 3.方法装饰器 */
/* 它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰器会在运行时传入下列三个参数:
1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象;
2.成员的名字;
3.成员的属性描述符。 */
function get(params:any)
{
return function(target:any,methodName:any,desc:any)
{
target.apiUrl = "xxx";
target.run = function()
{
console.log("this.url")
}
var oMethod = desc.value;
desc.value = function(...args:any[])
{
args.map((value)=>{return String(value)})
console.log(args)
oMethod.apply(this,args)
}
}
}
class HttpClient5{
public apiUrl:string|undefined
constructor()
{
}
@get('http://www.baidu.com')
getData(...args:any[])
{
console.log(args)
console.log("我是getdata")
}
}
var http5:any = new HttpClient5()
console.log(http5.apiUrl)
http5.run()
http5.getData(123,'xxx')
/* 4.方法参数装饰器 */
/* 参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据:传入下列3个参数:
1.对于静态成员来说是类的构造函数,对于实例成员是类的原型对象;
2.方法的名字;
3.参数在函数参数列表中的索引。 */
function logParams(params:any)
{
return function(target:any,methodsName:any,paramsIndex:any){
target.apiUrl = params
}
}
class HttpClient6{
public apiUrl:string|undefined
constructor()
{
}
getData(@logParams('uuid') uuid:any)
{
console.log(uuid)
}
}
var http6 = new HttpClient6()
http6.getData(123456)
console.log(http6.apiUrl)
/* 装饰器执行顺序 */
//属性》方法》方法参数》类,如果有多个同样的装饰器,它会先执行后面的
function llogClass1(params:string)
{
return function(target:any)
{
console.log("类装饰器1")
}
}
function llogClass2(params:string)
{
return function(target:any)
{
console.log("类装饰器2")
}
}
function logAttribute(params?:string)
{
return function(target:any,attrName:any)
{
console.log("属性装饰器")
}
}
function logmethod(params?:string)
{
return function(target:any,attrName:any)
{
console.log("方法装饰器")
}
}
function logParams1(params?:any)
{
return function(target:any,methodsName:any,paramsIndex:any){
target.apiUrl = params
console.log("方法参数装饰器1")
}
}
function logParams2(params?:any)
{
return function(target:any,methodsName:any,paramsIndex:any){
target.apiUrl = params
console.log("方法参数装饰器2")
}
}
@llogClass1("http://www.123.com")
@llogClass2("http://www.456.com")
class HttpClient7{
@logAttribute()
public apiUrl:string|undefined
constructor()
{
}
@logmethod()
getData()
{
return true
}
setData(@logParams1() attr1:any,@logParams2() attr2:any)
{
}
}
var http7 = new HttpClient7()
/* 输出: */
//属性装饰器
//方法装饰器
//方法参数装饰器2
//方法参数装饰器1
//类装饰器2
//类装饰器1