TypeScript入门知识
1. 基础
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持.
它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。
我们约定使用 TypeScript 编写的文件以 .ts 为后缀,用 TypeScript 编写 React 时,以 .tsx 为后缀。
ts 在对数值类型的定义的区别是:
在定义数据类型的时候,都是通过在变量的后面加冒号(:)+数据类型,来限定该变量的应该是一个什么数据类型的变量,当你对该变量进行初始化或者重新赋值时,假如数据类型和定义的不一样,这时ts就会在编译时报错。
let val :number=6;
let new:boolean=false;
let name:string ='Tom';
// 模板字符串
let sentence:string=`Hello,my name is ${name}`;
let u:undefinede=undefined;
let n:null=null;
TypeScript 只会进行静态检查,如果发现有错误,编译的时候就会报错。
TypeScript 编译的时候即使报错了,还是会生成编译结果
undefined和null是所有类型的子类型
而子类型赋值给父类型的变量,是不会报错的,反之则会;
undefined 类型的变量只能被赋值为 undefined,null 类型的变量只能被赋值为 null。
let num:number=undefined;
let str:string =null;
空值(void类型)
在 TypeScript 中,可以用 void 表示没有任何返回值的函数:
function alertName():void{
alert('My name is Tom');
}
定义变量也可以把变量定义成void类型,但一般没什么用,因为你只能将它赋值为 undefined 和 null。
let unusable:void=undefined;
注意:
void 类型的变量不能赋值给 number 类型的变量
let u:void;
let num:number=u;
//编译会报错
任意值类型
如果数据类型定义的是 any 类型,则允许被赋值为任意类型。
在任意值上访问任何属性都是允许的,也允许调用任何方法。
// 访问属性
let anything:anny='hello';
console.log(anything.myName);
console.log(anything.myName.firstname);
// 调用方法
let antThing:any='Tom';
anyThing.setName('Jerry');
anyThing.myName.setFirstName('Cat');
声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值
未声明类型的变量
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型:
let something;
somethig='seven';
something=7;
somthing.setName('Tom');
什么是类型推论?
如果没有明确指定某个变量的数据类型,那么ts会依照类型推论,推断出一个类型;
当变量定义的时候有赋值的话,那么第一个赋值的类型就会被推测为该变量的类型,之后如果定义的类型与初始赋值的类型不一致,就会报错;如果定义的时候没有赋值,那么该变量就会被识别为any类型,之后有没有赋值,改变量都不会被类型检查。
let val ='zhuzhuxia';
val=7; //报错
let val2;
val2='zhuzhzuxia';
val2=6; //不会被类型检查,不会报错
联合类型
表示取值可以为多种类型中的一种。
使用 | 分隔每个类型。
let num:string|number;
num='seven';
num=7;
// 这里表示num的数据类型可以是string或者number的一种;
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型
接口
是对行为的抽象,而具体如何行动需要由类(classes)去实现(implements)
TypeScript 中的接口,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
下面是定义接口的实例:
interface Person{
name:string;
age:number;
}
let tom:Person={
name:'tom';
age:24
};
上面的例子中,我们定义了一个接口 Person,接着定义了一个变量 tom,它的类型是 Person。这样,我们就约束了 tom 的形状必须和接口 Person 一致。
定义的变量比接口少了一些属性是不允许的,多一些属性也是不允许的.
赋值的时候,变量的形状必须和接口的形状保持一致
#### 可选属性
有时候我们希望不要完全匹配一个形状,那么可以把我们希望可选的属性,定义成可选属性;
可选属性:该属性可以不存在。但接口任然不允许添加未定义的属性。
interface Person{
name:string;
age?:number;
}
let tom:Person={
name:'tom';
age:24;
}
let tom:Person={
name:'tom';
}
任意属性
假如你希望你的接口允许有任意的属性,可以将接口定义为如下格式:
interface Person{
name:string;
age?:number;
[propName:string]:any;
}
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
只读属性
有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么就可以用readonly定义只读属性。
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 89757,
name: 'Tom',
gender: 'male'
};
tom.id = 9527;
//"Cannot assign to 'id' because it is a read-only property.",
注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
数组类型
数组的定义方式有多种:
1)[类型+方括号]表示法
let fibonacci: number[] = [1,4,3,4,6,7];
<!-- 联合类型和数组的结合 -->
let fal: (number|string)[]=[1,5,6,'4','8',0];
// 数组泛型
let finb: Array<number>=[1,2,3,4,5,3];
// 用接口表示数组
interface NumberArray{
[index:number]:number;
}
let fibarray: NumberArray=[1,3,4,5,67,5,8];
// any在数组中表示允许出现任何类型
let list:any[]=['Xcat Liu':25,{website:'http:xacdliu.com'}];