You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classAnimal{name:string;constructor(theName: string){this.name=theName;}move(distanceInMeters: number=0){console.log(`${this.name} moved ${distanceInMeters}m.`);}}// 使用extends实现继承classSnakeextendsAnimal{//包含构造函数的派生类必须调用super(),他会执行基类的构造方法constructor(name: string){super(name);}move(distanceInMeters=5){console.log("Slithering...");super.move(distanceInMeters);}}classHorseextendsAnimal{constructor(name: string){super(name);}//子类可以重写父类的放方法move(distanceInMeters=45){console.log("Galloping...");super.move(distanceInMeters);}}letsam=newSnake("Sammy the Python");lettom: Animal=newHorse("Tommy the Palomino");sam.move();tom.move(34);
classPerson{protectedname: string;protectedconstructor(theName: string){this.name=theName;}}// Employee can extend PersonclassEmployeeextendsPerson{privatedepartment: string;constructor(name: string,department: string){super(name);this.department=department;}publicgetElevatorPitch(){return`Hello, my name is ${this.name} and I work in ${this.department}.`;}}lethoward=newEmployee("Howard","Sales");letjohn=newPerson("John");// Error: The 'Person' constructor is protected
参数属性
在一个地方定义和初始化一个成员。
classAnimal{// private name:stringconstructor(privatename: string){}move(distanceInMeters: number){console.log(`${this.name} moved ${distanceInMeters}m.`);}}
abstractclassDepartment{constructor(publicname: string){}printName(): void{console.log('Department name: '+this.name);}abstractprintMeeting(): void;// 必须在派生类中实现}classAccountingDepartmentextendsDepartment{constructor(){super('Accounting and Auditing');// constructors in derived classes must call super()}printMeeting(): void{console.log('The Accounting Department meets each Monday at 10am.');}generateReports(): void{console.log('Generating accounting reports...');}}letdepartment: Department;// ok to create a reference to an abstract typedepartment=newDepartment();// error: cannot create an instance of an abstract classdepartment=newAccountingDepartment();// ok to create and assign a non-abstract subclassdepartment.printName();department.printMeeting();department.generateReports();// error: method doesn't exist on declared abstract type
// T用于捕获用户传入的类型,并用它作为返回值的类型functionidentity<T>(arg: T): T{returnarg;}letoutput=identity<string>("myString");// type of output will be 'string'letoutput=identity("myString");// type of output will be 'string'
泛型变量
泛型函数要求我们在函数体中正确使用这个传入的通用类型.
functionloggingIdentity<T>(arg: T): T{console.log(arg.length);// Error: T doesn't have .lengthreturnarg;}// 下面的写法是正确的functionloggingIdentity<T>(arg: T[]): T[]{console.log(arg.length);// Array has a .length, so no more errorreturnarg;}
interfaceLengthwise{length: number;}// 接口约束了传入的值必须有number类型的length属性functionloggingIdentity<TextendsLengthwise>(arg: T): T{console.log(arg.length);// Now we know it has a .length property, so no more errorreturnarg;}loggingIdentity(3);// Error, number doesn't have a .length propertyloggingIdentity({length: 10,value: 3});
// 用属性名从对象中获取属性值,通过约束来确保属性存在于对象上functiongetProperty<T,KextendskeyofT>(obj: T,key: K){returnobj[key];}letx={a: 1,b: 2,c: 3,d: 4};getProperty(x,"a");// okaygetProperty(x,"m");// error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
constnumberRegexp=/^[0-9]+$/;exportdefaultfunction(s: string){returns.length===5&&numberRegexp.test(s);}// 可以自己指定默认导出的变量名importvalidatefrom"./StaticZipCodeValidator";letstrings=["Hello","98052","101"];// Use function validatestrings.forEach(s=>{console.log(`"${s}" ${validate(s) ? " matches" : " does not match"}`);});
/** * Takes a string and adds "padding" to the left. * If 'padding' is a string, then 'padding' is appended to the left side. * If 'padding' is a number, then that number of spaces is added to the left side. */functionpadLeft(value: string,padding: number|string){if(typeofpadding==="number"){returnArray(padding+1).join(" ")+value;}if(typeofpadding==="string"){returnpadding+value;}}padLeft("Hello world",4);// returns " Hello world"letindentedString=padLeft("Hello world",true);// errors during compilation
interfaceBird{fly();layEggs();}interfaceFish{swim();layEggs();}functiongetSmallPet(): Fish|Bird{// ...}// 当一个值是联合类型时,我们只能访问所有类型的共有成员letpet=getSmallPet();pet.layEggs();// okaypet.swim();// errors// 检查成员是否存在,需要增加类型断言if((<Fish>pet).swim){(<Fish>pet).swim();}else{(<Bird>pet).fly();}// 用户自定义类型保护functionisFish(pet: Fish|Bird): pet is Fish{return(<Fish>pet).swim!==undefined;}if(isFish(pet)){pet.swim();}else{pet.fly();}
typeof作为类型保护
functionpadLeft(value: string,padding: string|number){if(typeofpadding==="number"){returnArray(padding+1).join(" ")+value;}if(typeofpadding==="string"){returnpadding+value;}thrownewError(`Expected string or number, got '${padding}'.`);}
typeEasing="ease-in"|"ease-out"|"ease-in-out";classUIElement{animate(dx: number,dy: number,easing: Easing){if(easing==="ease-in"){// ...}elseif(easing==="ease-out"){}elseif(easing==="ease-in-out"){}else{// error! should not pass null or undefined.}}}letbutton=newUIElement();button.animate(0,0,"ease-in");button.animate(0,0,"uneasy");// error: "uneasy" is not allowed here
TypeScript——类
基于类的面向对象的编码风格。
基础
继承
修饰符
TS中,成员默认为
public
,我们也可以手动将其标记为public
。private
被标记为
private
的成员,不可以从类的外部访问。如果其中一个类型里包含一个private
成员,那么只有当另外一个类型中也存在这样一个private
成员, 并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。protected
protected
成员在派生类中仍然可以访问,构造函数被标记为protected
意味着他不能再包含他的类外被实例化,但是能被继承。参数属性
在一个地方定义和初始化一个成员。
存取器
静态属性
每个实例都要访问这个属性。
抽象类
作为其他派生类的基类使用,一般不直接被实例化。抽象类中的抽象方法不包含具体实现且必须在派生类中实现。
高级技巧
构造函数
把类当做接口使用
TypeScript——泛型
创建支持多种数据类型的可重用的组件。
基本
泛型变量
泛型函数要求我们在函数体中正确使用这个传入的通用类型.
泛型接口
泛型类
泛型约束
我们不仅可以通过泛型变量中提到的传入正确的通用类型来约束泛型变量,也可以通过接口来描述约束条件。
TypeScript——模块
基础
模块在其自身的作用域里执行,不在全局作用域里。
导出语句
导入
默认导出
使用其他的JavaScript库
TypeScript——枚举,类型推论,类型兼容性,高级类型
枚举
定义一些有名字的数字常量,使用
enum
关键字。类型推论
类型兼容性
如果x要兼容y,那么y至少具有与x相同的属性。
比较两个函数的类型兼容性
高级类型
交叉类型
多在混入(
mixins
)时使用,将多个类型合并为一个类型。联合类型
一个值可以是几种类型之一。
typeof作为类型保护
instanceof 类型保护
字符串字面量类型
TypeScript——接口
为对象类型命名,定义相关契约。
基本用法
可选属性
一方面对可能存在的属性进行预定义,另一方面可以捕获引用了不存在的属性的错误。
只读属性
额外的属性检查
如果使用可选属性,但却传入了可选属性外的属性,依然会报错(将对象向字面量赋值给另一个变量,可以绕过这一检查)。如果确认除了定义好的属性还可能传入任意数量的属性时,可以这样定义:
描述函数类型
可索引的类型
类类型——实现接口
继承接口
更灵活地将接口分割到可重用的模块里。
混合类型
一个对象同时作为函数和对象使用。
TypeScript——Symbols
基本类型,通过
Symbol
构造函数创建。可迭代性
实现了
Symbol.iterator
属性的对象时可迭代的,该函数负责返回供迭代的值。for..of & for..in
for..of
迭代对象的键值(value)并且可以用来迭代set,map
,for..in
迭代键(key)。The text was updated successfully, but these errors were encountered: