在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1.TypeScript 基础类型在TypeScript与JavaScript中几乎有相同的数据类型,不同的是TypeScript更严格,在定义一个变量时需要声明数据类型。如果不声明,都认定为 Any 类型。 a.布尔值最基本的数据类型就是简单的true/false值 let isDone: boolean = false;
b. 数字 TypeScript里的所有数字都是浮点数。 这些浮点数的类型是 let decLiteral: number = 6; let hexLiteral: number = 0xf00d; let binaryLiteral: number = 0b1010; let octalLiteral: number = 0o744; c.字符串字符串用法较多,常用有两种。 1.定义变量 let name:string = "momo"; 2.字符串模版 let name1:string = "wang"; let age:number = 24; let sences:string = `hello ,my name is ${name}.i am ${age} years old` d.数组 TypeScript像JavaScript一样可以操作数组元素。 有两种方式可以定义数组。 第一种,可以在元素类型后面接上 let list:number[] = [1,2,3] 第二种方式是使用数组泛型, let list:Array<number> = [1,2,3]; e.元组元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 let x:[string,number]; x = ['hello', 10]; // ok x = [10,'hello']; // error f.枚举
enum Color {Red,Green ,Blue} let c:Color = Color.Green; console.log(c); // 0 默认情况下,从 enum Color {Red = 1,Green ,Blue} let c:Color = Color.Green; console.log(c); // 2 枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字: enum Color {Red = 1,Green ,Blue} let colorNumber:string = Color[2]; console.log(colorNumber); // Green g.Any有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 let notSure:any = 4; notSure = 'momo'; notSure = false; h.void 某种程度上来说, 声明一个 let unusable:void = undefined;
2.变量声明
let 和 const在ES6中有详细解释说明,这里就不多阐述了。 3.数组数组解构let input = [1, 2]; let first = input[0], second = input[1]; console.log(first); 这创建了2个命名变量 first = input[0];
second = input[1];
你可以在数组里使用 let [first, ...rest] = [1, 2, 3, 4]; console.log(first); // 1 console.log(rest); // [ 2, 3, 4 ] 对象解构let o = { a: "foo", b: 12, c: "bar" }; let { a, b } = o; 这通过 就像数组解构,你可以用没有声明的赋值: ({ a, b } = { a: "baz", b: 101 }); 要小心使用解构。 从前面的例子可以看出,就算是最简单的解构表达式也是难以理解的。 尤其当存在深层嵌套解构的时候,就算这时没有堆叠在一起的重命名,默认值和类型注解,也是令人难以理解的。 解构表达式要尽量保持小而简单。 你自己也可以直接使用解构将会生成的赋值表达式。 4.接口TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。 接口初探function text(lableObj) { console.log(lableObj.lable); } var myObj = { size: 10, lable: "size 10" }; text(myObj); //size 10 类型检查器会查看text的调用。 text有一个参数,并要求这个对象参数有一个名为 需要注意的是,我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必需的属性是否存在,并且其类型是否匹配。 然而,有些时候TypeScript却并不会这么宽松,我们下面会稍做讲解。
下面我们重写上面的例子,这次使用接口来描述:必须包含一个 interface lableValue{ lable:string; } function text(lableObj:lableValue){ console.log(lableObj.lable); } let myObj = {size:10,lable:"size 10"} text(myObj); //size 10
它代表了有一个 需要注意的是,我们在这里并不能像在其它语言里一样,说传给text的对象实现了这个接口。 我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。 还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。 可选属性接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。 可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值了。 interface SquareConfig{ color?: string; width?: number; } function creatSquare(config:SquareConfig):{color:string,area:number}{ let newSquare = {color:"white",area:0}; if(config.color){ newSquare.color = config.color; } if(config.width){ newSquare.area = config.width; } return newSquare; } let mySquare = creatSquare({color:"black"}) console.log(mySquare); //{ color: 'black', area: 0 } 带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误。 值得一提的是,被圈上的部分是函数creatSquare的返回值,如果函数没有返回值,应该标记为:void。
只读属性 一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 interface Point{
readonly x:number;
readonly y:number;
}
如果传入参数时,传入了接口中没有的参数,比如: interface SquareConfig{ color?: string; width?: number; } function creatSquare(config:SquareConfig):{color:string,area:number}{ let newSquare = {color:"white",area:0}; if(config.color){ newSquare.color = config.color; } if(config.width){ newSquare.area = config.width; } return newSquare; } let mySquare = creatSquare({colour:"black"}) 这个时候会得到一个错误,// error: 'colour' not expected in type 'SquareConfig' 解决办法: 最佳的方式是能够添加一个字符串索引签名,前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性。 如果 interface SquareConfig { color?: string; width?: number; [propName: string]: any; } 我们稍后会讲到索引签名,但在这我们要表示的是
函数类型除了描述带有属性的普通对象外,接口也可以描述函数类型。 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。 interface SearchFunc{ (source:string,subString:string):boolean; } 这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。 下例展示了如何创建一个函数类型的变量,并将一个同类型的函数赋值给这个变量。 interface SearchFunc{ (source:string,subString:string):boolean; } let mySearch:SearchFunc; mySearch = function(source:string,subString:string){ let result = source.search(subString); return result > -1; } 对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 比如,我们使用下面的代码重写上面的例子: interface SeachFunc{ (source:string,subString:string):boolean; } let mySeach:SeachFunc; mySeach = function(src:string,sub:string):boolean{ let result = src.search(sub); return result > -1; } 函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的。 如果你不想指定类型,TypeScript的类型系统会推断出参数类型,因为函数直接赋值给了 函数的返回值类型是通过其返回值推断出来的(此例是 如果让这个函数返回数字或字符串,类型检查器会警告我们函数的返回值类型与 可索引的类型 与使用接口描述函数类型差不多,我们也可以描述那些能够“通过索引得到”的类型,比如 可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。 interface StringArray{ [index:number]:string; } let myArray:StringArray; myArray = ["bob","fred"]; let myStr = myArray[0]; console.log(myStr); //bob 共有支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 也就是说用 class Animal { name: string; } class Dog extends Animal { breed: string; } // 错误:使用数值型的字符串索引,有时会得到完全不同的Animal! interface NotOkay { [x: number]: Animal; [x: string]: Dog; } 你可以将索引签名设置为只读,这样就防止了给索引赋值: interface ReadonlyStringArray { readonly [index: number]: string; } let myArray: ReadonlyStringArray = ["Alice", "Bob"]; myArray[2] = "Mallory"; // error!
总结:1.interface SeachFunc {}; 相当于定义了类型,并且只能按照这个类型传值; 2.let mySeach:SeachFunc; 相当于具体了内容,进行怎么样的操作; 3.let myObj = mySeach("wang","w"); 相当于实例化;
5.类下面看一个使用类的例子: class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet():string { return "Hello, " + this.greeting; } } let greeter = new Greeter("world"); console.log(greeter.greet()); //Hello, world 我们声明一个 你会注意到,我们在引用任何一个类成员的时候都用了 最后一行,我们使用 继承在TypeScript里,我们可以使用常用的面向对象模式。 基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。 class Animal{ move(distanceInMeters:number = 0){ console.log(`Animal moved ${distanceInMeters}`); } } class Dog extends Animal{ bark(){ console.log("woof!woof!"); } } const dog = new Dog(); dog.bark(); //woof!woof! dog.move(10);//Animal moved 10 dog.bark();//woof!woof! 这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, 因为
class Animal { name: string; constructor(theName: string) { this.name = theName; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters}m.`); } } class Snake extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 5) { console.log("Slithering..."); super.move(distanceInMeters); } } class Horse extends Animal{ constructor(name: string) { super(name); } move(distanceInMeters = 45){ console.log("Galloping..."); super.move(distanceInMeters); } } let sam = new Snake("Sammy the Python"); let tom:Animal = new Horse("Tommy the Palomino"); sam.move(); tom.move(34); 这个例子展示了一些上面没有提到的特性。 这一次,我们使用 与前一个例子的不同点是,子类包含了一个构造函数,它 必须调用 而且,在构造函数里访问 这个例子演示了如何在子类里可以重写父类的方法。 注意,即使
|
请发表评论