TypeScript是微软开发的JavaScript的超集,TypeScript兼容JavaScript,可以载入到JavaScript代码。其实两者的关系也就相当于.java文件与.class文件的关系。TypeScript中加入了注释,让编译器理解所支持的对象和函数,但编译过程中会移除,不会增加开销。
1.基本数据类型
(1)Boolean
//Boolean
var isDone:boolean=false;
(2)Number
//Number
var width:number=100;
(3)String
//String
var name:String="hello";
(4)Array
//Array
var list:number[]=[1,2,3];
var list:Array<number>=[1,2,3];
(5)Enum(枚举)
//Enum
enum Color {Red,Blue,Green}
var c:Color=Color.Red;
alert(c);//默认值从0开始,alert(0);
//可以手动指定值
enum Color1 {Red=1,Green,Blue}
var c1:Color1=Color1.Green;
alert(c1);//alert(2)
//根据值查找名称
enum Color2 {Red=1,Green=2,Blue=4}
var c2:string =Color2[4];
alert(c2);//alert(Blue)
(6).Any(不确定数据类型)
//不确定类型,退出编译检查
var notSure: any = 4;
notSure ="maybe a String";
notSure = false;
//不确定数组元素类型
var anylist:any[] =[1,true,"free"];
anylist[1]=100;
(7).void
//空白
function warnUser() : void{
alert(123);
}
2.类
基本语法
class Animal{
animalName:string;
constructor(name:string){ //类的构造器 相当于java中的构造函数
this.animalName=name;
}
sayHello(){
alert(this.animalName+":Hello");
}
}
var tom=new Animal("Tom");
tom.sayHello();//生成对象 调用sayHello方法。
继承
class Animal{ //父类
animalName:String;
constructor(name:String){
this.animalName=name;
}
sayHello(){
alert(this.animalName+":Hello");
}
}
class Cat extends Animal{
sayHello(){
alert(this.animalName+"(cat):"+"Hello");//子类重写父类的方法
}
}
class Mouse extends Animal{
sayHello(){
alert(this.AnimalName+"(mouse):"+"Hello");
}
}
var tom:Animal=new Cat("tom");
tom.sayHello();//alert(Tom(Cat):Hello)
var jerry:Animal=new Mouse("jerry");
jerry.sayHello();//alert(Jerry(Mouse):Hello)
修饰符 private
当把animalName的属性改为private(私有时)
class Animal{
private animalName:string;//默认的情况下是public
constructor(name:string){
this.animalName=name;
}
//........
}
class cat extends Animal{
sayHello(){
alert(this.animalName+"(cat):"+"Hello");//Error编译不通过 private修饰的变量只能本类访问,子类不能访问
}
}
get set访问器
class Aniaml{
private animalName:string;//默认是public
get animalName():string{ //返回值类型也可以不写 它会自动判断
return this.animalName;
}
set animalName(name:String){
this.animalName=name;
}
}
静态属性
class Table{
static width=100;
static height=200;
}
var width=Table.width;
alert(width);//alert(100) 静态属性会随着类的加载而加载,可以直接用类名调用静态属性和静态方法
3.接口
基本语法
interface Icar{
color:string;
}
class Bus implements Icar{
color:string;
constructor(){
this.color="Blue";
}
}
var bus=new Bus();
alert(bus.color) //alert(Blue)
继承接口
interface Shape{
color:string;
}
interface penStroke{
penWidth:number;
}
interface Square extends Shape,penStroke{
sideLength:number;
}//此时接口interface同时具有3个属性
可选属性
interface InCar{
color:string;
safe?:any; //此时表示该属性是可选类型 实现类无需实现
}
function MoveCar(car:InCar){
if(car.safe){
alert("The car is safe");
}
else{
alert("The car is not safe");
}
}
4.模块(modules)
作用:1.防止命名空间重复 2.将一个功能模块很容易划分到不同的文件中,更容易维护。
基本语法
module MyDemo{
export interface Idemo{
}
export class Demo implements Idemo{
}
}
别名
module Shapes{
export module Polygons{
export class Triangle{ }
export class Square{ }
}
}
import polygons=Shapes.Polygons;
var sq=new polygons.Square(); //类似于'new Shape.Polygons.Square()'
模块构造出了一个独立的作用域,模块内的变量、函数、类在模块外部不可见;如果想要暴露 A 模块内的 a 函数给 B 模块,需要在 A 中使用 export 语法,同时在 B 模块中 import 从 A 暴露出的 a 函数(可以改变 B 中引用的函数名称);这是模块成员间的通信;
两个模块级别关系的建立是通过 imports 和 exports 实现的,也就是文件路径的关联;
模块间的通信和导入,依赖于模块加载器,如:CommonJS(nodejs)、RequireJS(web);
TypeScript 中,任何包含了顶级 import 或者 export 的文件都会被当成一个模块;
1.animal.ts里声明了一个类Animal,通过export导出。在app.ts里,指定相对文件路径,通过import导入,就可以使用Animal类了。
//animal.ts
export class Animal{
name:string;
show():string{
return this.name;
}
}
//app.ts
import {Animal} from './animal';
let dog=new Animal();
dog.name='狗狗';
dog.show();
2.模块的导入,导出使用的是默认的内部对象名称,但也可以重命名。
class Animal{
name:string;
show():string{
return this.name;
}
}
export {Animal as ANI}
import {ANI as Animal} from './animal';
let dog=new Animal();
dog.name='狗狗';
dog.show();
此时重命名前的名称和重命名后的要相同,在不知道导入模块的名称是,可以用*代替。
import * as animal_module from './animal';
3.默认导出
一个模块的默认导出只能有一个
在上面的例子里,通过default关键字,将Animal类导出。与一般的导入不同的是,导入默认的导出模块时,可以直接指定导入的模块名称,而不需要用{}花括号括起来。
class Animal{
name:string;
show():string{
return this.name;
}
}
export default Animal;
import Animal from './animal'; //导入默认的导出模块时,类名可以不用{}括起来。
let dog=new Animal();
dog.name='狗狗';
dog.show();
4.动态里载模块
因为在JavaScript里,模块加载方式分别有两种:CommonJS和AMD。
CommonJs方式引用:
app.ts
// 定义加载方法
2 declare function require(moduleName: string): any;
3
4 import {Animal} from './animal';
5
6 if (true) {
7 let Animal_Type: typeof Animal = require('./animal');
8 let dog = new Animal_Type();
9 dog.name = '狗狗';
10 dog.show();
11 }
AMD方式引用:
// 定义加载方法
2 declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void;
3
4 import {Animal} from './animal';
5
6 if (true) {
7 require(["./animal"], (Animal_Type: typeof Animal) => {
8 let dog = new Animal_Type();
9 dog.name = '狗狗';
10 dog.show();
11 });
12 }
5.函数(Function)
1. 基本语法
function add(x:number,y:number):number{
return x+y;
}
//or
var myadd=function (x:number,y:number):number{
return x+y;
}; //后者没有函数名和末尾要加上分号
2.完整的函数类型
var myadd:(x:number,y:number)=>number=
function (x:number,y:number):number{
return x+y;
}
函数要包括参数列表和返回值,参数列表包括名字和类型。对于返回值,我们在函数和返回值类型之间使用了=>符号,使其清晰明了。
为了增强可读性,我们给x,y实际的意义。
var myadd:(basenumber:number,increment:number)=>number=
function (x:number,y:number):number{
return x+y;
}
第二部分的number是函数的返回值类型,若无返回值的话,则为void.
第三部分的function参数类型,根据上下文自行判断,可以省略。
3.可选参数
在JavaScript中每个参数都是可选的,没传参的,值就是undefined。在TypeScript中,我们可以在参数名旁用?来标记可选参数。
可选参数必须放在必须参数的后面。
function buildName(firstName:string,lastName?:string){ //lastName就是可选参数,他必须放在必须参数firstName后面
if(lastName){
return fistName+lastName;
}
else{
return firstName;
}
}
4.默认参数
在TypeScript中,可以为一个参数设置一个默认的值,当用户没有传入这个参数值,后者值为undefined时,这个默认值起作用。
function buildName(firstName: string, lastName = "Smith") { //lastName="Smith"就是默认参数
return firstName + " " + lastName;
}
5.可变参数(剩余参数)
当你想操作多个参数,但是你又不知道有多少个参数传进来时。
function buildName(fistName:string,...restofName:string[ ]){
return firstNmae+" "+restofName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
编译器创建参数数组,名字是你在省略号( ...
)后面给定的名字,你可以在函数体内使用这个数组。
这个省略号也会在带有剩余参数的函数类型定义上使用到:
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
6.Lambads和this关键字
var people={
name:["张三","李四","王五","赵六"],
getName:function(){
return function(){
var i=Math.floor(Math.random()*4);
return {
n:this.name[i]
}
}
}
}
var pname=people.getName();
alert("名字:"+pname().n);
此时这个this指向的不是people。调用发现getName中的this关键字指向的是getName,访问不到外部的name属性。
可以用lambads表达式"()=>"修改,箭头函数能保存函数创建时的 this
值,而不是调用时的值。
var people = {
name: ["张三", "李四", "王五", "赵六"],
getName: function () {
return ()=> {
var i = Math.floor(Math.random() * 4);
return {
n: this.name[i]
}
}
}
}
var pname = people.getName();
alert("名字:" + pname().n);
7.重载
JavaScript本身就是动态语言,函数根据传入不同的参数而返回不同类型的数据是很常见的。
//重载
function student(name:string):string;
function student(age:number):number;
function student(numberorage:any):any {
if (numberorage && typeof (numberorage) == "string")
alert("姓名");
else
alert("年龄");
}
student("Tom");//alert("姓名")
student(15);//alert("年龄")
6.泛型
1.基本语法
function identity<T>(arg:T):T{
return arg;
}
//数组泛型
function identity<T>(arg:T[]):T[]{
console.log(arg.length);
}
T帮我们捕获用户的传入类型,也可以使用T来当作返回值类型。
有两种方式使用:
let output=identity<string>("mystring")//第一种
let output=identity("mystring")//第二种更普遍,用到了类型推论。
2.泛型类型(通用的函数类型)
function identity<T>(arg:T):T{
return arg;
}
var myIdentity:<T>(arg:T)=>T=indentity; //T也可以用其他字母代替
var myIdentity:{<T>(arg:T):T}=indentity; //第二种写法
3.接口泛型
interface GenericIdentityFn{
<T>(arg:T):T;
}
function identity<T>(arg:T):T{
return arg;
}
var myIdentity:GenericIdentityFn=identity;
4.泛型类
class GenericNumber<T> {
zeroValue:T;
add:(x:T, y:T) => T;
}
var myGenericNumber = new GenericNumber<number>(); //也可以定义成其他类型的
myGenericNumber.zeroValue = 0; //此时的T是number类型的
myGenericNumber.add = function (x, y) {
return x + y;
};
5.泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg:T):T{
console.log(arg.length);
return arg;
}
loggingIdentity(3);//error
loggingIdentity({length: 10, value: 3}); //只要类型包含length属性即可
6.泛型类约束
class Findable<T>
{
//...
}
function find<T>(n: T, s: Findable<T>) {
// ...
}
7.合并
1.合并接口
interface Box{
height:number;
width:number;
}
interface Box{
scale:number;
}
var box:Box={height:2,width:3,scale:4};
合并模块
module Animal{
export class Zebra{}
}
module Animal{
export interface Leggle { numberOfLegs: number; }
export class Dog{ }
}
//相当于
module Animals {
exportinterface Legged { numberOfLegs: number; }
exportclass Zebra { }
exportclass Dog { }
}
合并类与模块
class Album {
label:Album.AlbumLabel;
}
module Album {
export class AlbumLabel {
}
}
合并模块与函数
function buildLabel(name:string):string {
return buildLabel.prefix + name + buildLabel.suffix;
}
module buildLabel {
export var suffix = "";
export var prefix = "Hello, ";
}
alert(buildLabel("Sam Smith"));
合并模块与枚举
enum Color {
red = 1,
green = 2,
blue = 4
}
module Color {
export function mixColor(colorName:string) {
if (colorName == "yellow") {
return Color.red + Color.green;
}
else if (colorName == "white") {
return Color.red + Color.green + Color.blue;
}
else if (colorName == "magenta") {
return Color.red + Color.blue;
}
else if (colorName == "cyan") {
return Color.green + Color.blue;
}
}
}
不能合并:
- 类与类不能合并
- 接口与类不能合并
- 变量与类不能合并
转载请注明出处:https://blog.csdn.net/x_christ1/article/details/83380744
本文来源于:TypeScript中文网:https://www.tslang.cn/docs/home.html
xiaocong_soft的TypeScript 基本语法:https://www.cnblogs.com/xcong/p/4570235.html