提供其他语言优点的语法支持。
数据类型
数据声明必须有明确的类型。使用符号:
声明。
boolean
number
string
// 布尔
let bool:boolean = true;
// 数值
let num:number = 10;
// 字符串
let str:string="hello";
数组定义
let count:number[] = [3,4,5];
// 或者
let list:Array<number> = [4,5,6];
元组:声明一个已知元素数量和元素类型的数组。
let arr:[string,number];
arr = ["world",20];
如果赋值元素下标超出声明的数量(数组越界),则按照该值是否为已有的类型;
该值类型为联合类型
arr[3] = "name";
arr[4]=true;// 报错,arr中不包含布尔类型,只有(string|number)可正常赋值。
枚举 :为一组数值赋予名称
enum name {hh,gg,tt}
// 默认从 0 开始
let h:name = name.hh; // h:0
// 手动赋值
enum name {hh=3,gg=5,tt=0}
let h:name = name.hh; // h:3
// 通过编号去找名称
let str:string = name[5]; // str:"gg"
any
:对于不确定类型的变量声明
let age:any=45;
// 数组声明
let arr:any[] = [3,"true",true];
使用
Object
声明类型时,只允许赋任意值,却不能调用任意方法。即便这个方法存在。
void
: 没有任何类型
可声明函数返回值类型为 void
function fn():void{//...}
// 声明变量,只能复制 null、undefined
let unable:void = null;
null 、undefined
是所有类型的子类。可使用--strictNullChecks
标记后只能赋值自身和void
.
let num:number = null;
// 标记后
let n:null = null;
nerver
:表示永不存在值的类型
是所有类型的子类。没有类型可以赋值给nerver
,只有自身。
// 作为函数返回值类型,
function error():nerver{
throw new Error("nerver arrive");
}
函数必须存在无法达到的终点,
Error
,while(true){}
object
:表示非原始值类型。声明除基本类型之外的类型。
类型断言:即告诉编译器这个变量是什么类型,不管他声明的是什么。
let str:any = "hello world";
let name:number = (<string>str).length;
// as 写法
let name:number = (str as string).length;
typescript对接了ES6等最新的语法特性;
接口
为类型命名、规范定义代码。关键字interface
interface UserInterFace{
name:string;
age:number;
address?:string;
}
function addUser(user:UserInterFace){
console.log(user.name);
}
// 调用
let obj = {name:"小李子",age:23};
addUser(obj);
接口中定义的属性是必须传入的。如果属性后带有
?
则为可选,如address
;
针对传入额外的属性
addUser({name:"小李子",age:23,job:"IT"}); // error: job is't exist
// 类型断言可以绕开检查
addUser({name:"小李子",age:23,job:"IT"} as UserInterFace);
// 或使用字符串索引签名,表示任意类型
interface UserInterFace{
name:string;
age:number;
address?:string;
[prop:string]:any; // 除了规定传入的参数之外的属性
}
// 或一变量的形式传参
let obj = {name:"小李子",age:23,job:"IT"};
addUser(obj);
使用关键字readonly
定义属性只读,不可修改;ReadonlyArray<T>
类型定义创建数组后不可修改。
interface UserInterFace{
readonly name:"大强";
}
let num:ReadonlyArray<number> = [3,4,5];
num[0] = 12; // error!
使用接口表示函数类型
定义函数参数类型
/返回值类型
,在接口中定义调用签名
// 调用签名
interface SearchFun{
(str:string,subString:string):boolean; // 函数参数类类型、返回值类型
}
// 使用
let testSearch:SearchFun;
testSearch = function(str:string,target:string){ // 参数类型必须对应
return str.search(target)>-1; // 返回值类型必须对应
}
索引类型
定义对象的索引类型
、索引值类型
。在接口中定义索引签名
// 索引签名
interface IndexArrary{
[index:number]:string;
}
let arr:IndexArray = ["123","234"];
console.log(arr[0]); // "123"
// 设置索引签名只读属性,则不允许修改值
interface IndexArrary{
readonly [index:number]:string;
}
实现接口
定义公共属性、方法。类必须实现拥有。
interface UserInterface{
name:string;
updateName(str:string);
}
class User implements UserInterface{
name:string;
updateName(str:string){
this.name = str;
}
constructor(){} // 构造函数
}
接口继承
模块化使用,代码复用。
interface Person{
name:string;
}
interface User extends Preson{
age:number;
}
// 多继承
interface Work{
address:string;
}
interface Man extends User,Work{
responsibility:string;
}
let boy = <Man>{};
接口继承类
使用接口继承类类型;可以获取集成到该类的所有成员(不包括实现);这接口只能被器这个类或其子类实现。private
/protected
Class Control{
private name:string;
}
interface FormControl extends Control{
select(type:string):boolean;
}
// 子类实现
class Input extends Control implements FormControl{
select(type:string){
return true;
}
}
class Select extends Control{ // 不用实现FormControl 也会有select方法?不明白...
select(type:string){
return true;
}
}
混合类型
一个对象既可以当函数使用,也可以当对象使用。
interface User{
(name: string): string;
age: number;
addAddress(): void;
}
function userInfo(): User{
let user= <User>function (name: string):string {
return "boy";
};
user.age= 23;
user.addAddress = function () { };
return user;
}
let c = userInfo();
类
同ES6语法。
class User{
name:string;
constructor(str:string){
this.name = str;
}
getName(){
return "This is "+this.name;
}
}
let user = new User("大强");
继承
关键字extends
class Worker extends User{
constructor(str:string){
super(str);
}
getName(){
return "child :This is " +this.name;
}
}
let teacher:User = new Worker("gardener");
子类的构造函数必须先调用
super()
,
子类继承父类的属性、方法;内部可重写父类的方法。
修饰符
默认声明public
private
不能再声明它的类外部访问。修饰构造函数时则不能被实例化。
protected
与private
不同的是它可以被其派生类访问。
readonly
修饰只读,必须在声明时或构造 函数中初始化。
class test{
readonly name:string = "test";
constructor(readonly age:number){} // 将声明、赋值放在一起
}
存取器
使用getter
/setter
截取对对象成员的访问。
class User(){
private name:string;
set name(newname:string){
this.name = newname;
}
get name():string{
return this.name;
}
}
没有
set()
方法时默认只读。
静态属性
关键字static
修饰,不需要实例化类就可以访问类名.属性名
抽象类
作为基类使用,不会被实例化。只会被继承。
使用关键字abstract
修饰,抽象类或者类内部定义抽象方法。
abstract class Base{
constructor(public name: string) {
}
printName(): void {
console.log('base name: ' + this.name);
}
abstract addName(): void; // 抽象方法必须在派生类中实现
}
函数
与JavaScript不同的时指定了函数的参数类型
、返回值类型
;以及各种声明函数的方式。
// 常规
function getUser(id:string):string{
return "test";
}
// 函数类型式声明
let name:(id:string)=>string=function(id:string):string{return "test"};
// 按照推断类型,程序会地段判断出对应位置上的属性类型
let name:(id:string)=>string=function(id){return "test"};
可选、默认参数
typescript
中函数必须传入足够的参数
?
标识参数为可选参数;
剩余参数指不知道函数会传入多少个参数进来,使用...
标识数组类型;在必传参数之后。
// 可选参数、必须置于必传参数之后
function user(name:string,age?:number){};
// 参数默认值
function user(name:string,age=32){};
// 剩余参数
function user(name:string,...prop:string[]){};
重载
在JavaScript
中函数调用没有严格的参数个数、类型校验,方法名重复时后面的只会覆盖后面的。
在typescript
中有这些校验,那就可以实现重载
。
function addUser(name:string):boolean;
function addUser(user:{name:string,age:number}):boolean;
参考地址:
TypeScript 中文网