本地在node环境运行ts文件
//全局安装typescript和ts-node
npm install -g typescript
//npm install -g typescript-node 由于typescript-node不支持更高版本的ts
npm install -g ts-node //typescript@>=2.7
终端输入ts-node 文件名.ts即可例如下例:
ts-node xxx.ts
基础概念:
1. 在 TS 中,使用 :
指定变量的类型。
2. TS 只在编译时对类型进行静态检查,在运行时不会。
3. TS 编译的时候即使报错了,还是会生成编译结果,如果要在报错的时候终止 js 文件的生成,可以在 tsconfig.json 中配置 noEmitOnError 。
原始数据类型:数值(number)、字符串(string)、boolean(布尔)、null、undefined、Symbol、和BigInt
特别注意:
1.1、Void:在 TS 中,可以用 void
表示没有任何返回值的函数
function logName(): void {
console.log('pany')
}
1.2、在 TS 中,可以使用 null
和 undefined
来定义这两个原始数据类型
let u: undefined = undefined;
let n: null = null;
1.3、任意值(Any)如果一个普通类型在赋值过程中改变类型是不被允许的;但如果是 any
类型,则允许被赋值为任意类型:
let myFavoriteNumber: string = 'seven';
myFavoriteNumber = 7;
// 编译报错:Type 'number' is not assignable to type 'string'.
let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;
// 编译成功
1.5、任意值 any:变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型;
1.6、类型推论:TS 会在没有明确的指定类型的时候推测出一个类型(这就是类型推论);如果定义的时候没有赋值,会被推断成any类型,参考上1.5节:任意值 any
1.7、联合类型:使用 |
分隔每个类型
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
// 编译成功
一、对象的类型(接口):
1、interface 是对象的模板,可以看作是一种类型约定,中文译为“接口”。使用了某个模板的对象,就拥有了指定的类型结构。
//定义了一个Person接口
interface Person {
firstName: string;
lastName: string;
age: number;
}
//实现该接口很简单,只要指定它作为对象的类型即可。
const P:Person={
firstName: 'John',
lastName: 'Smith',
age: 25
};
上面示例中,变量p的类型就是接口Person
2、对象的可选属性
//可选属性就在属性名后面加一个问号
interface Person{
name: string;
age?: number; // 可选属性 age
}
let pany: Person ={
name: 'pany'
}
3.1、对象的属性索引
3.1.1、属性的字符串索引
interface A {
[prop: string]: number;
}
//上面示例中,[prop: string]就是属性的字符串索引,表示属性名只要是字符串,都符合类型要求。
属性索引共有string、number和symbol三种类型。
//一个接口中,最多只能定义一个字符串索引。字符串索引会约束该类型中所有名字为字符串的属性。
interface MyObj {
[prop: string]: number;
a: boolean; // 编译错误
}
//上面示例中,属性索引指定所有名称为字符串的属性,它们的属性值必须是数值(number)。属性a的值为布尔值就报错了。
3.1.2、属性的数值索引
// 属性的数值索引,其实是指定数组的类型
interface A {
[prop: number]: string;
}
const obj:A = ['a', 'b', 'c'];
// 上面示例中,[prop: number]表示属性名的类型是数值,所以可以用数组对变量obj赋值。
注意:如果一个 interface 同时定义了字符串索引和数值索引,那么数值索引必须服从于字符串索引。因为在 JavaScript 中,数值属性名最终是自动转换成字符串属性名。
3.2、接口的任意属性
interface Person {
name string;
age?:number;
[propName: string]: any//属性名取string类型;属性值取any(任意值)
}
let pany: Person ={
name: 'Tom',
gender: 'male'
}
注意:定义了任意属性且属性取string类型(除此之外还有number类型,常用于类数组),那么确定属性
和可选属性的类型都必须是它的属性值类型的子集
(说人话就是:如果定义了任意属性且取了string类型,那么属性和可选属性的类型必须是它属性值的子集
,在这也就是propName的属性值string的子集(也就是变量pany的属性值必须都是字符串类型的值)
interface Person{
name: string;
age?:number;
[propName: string]: string
}
let pany: Person = {
name: 'pany',
age: 25,
gender: 'male'
};
// 编译错误:因为可选属性 age 的类型(number)不是任意属性的类型(string)的子类型
注意2:一个接口只能有一个任意属性,如果接口中有多个类型的属性,则可以在任意属性中使用联合类型
interface Person {
name: string;
age?: number;
[propName: string]: string | number | undefined
}
let pany: Person={
name:'pany',
age: 25,
gender:'male
}
3.3、只读属性
// 属性是只读的,需要加上readonly修饰符。
interface Person {
readonly id: number; // readonly 只读
name: string;
age?: number;
[propName: string]: any;
}
let pany: Person = {
id: 1,
name: 'pany',
gender: 'male'
};
pany.id = 2;
// 编译错误:Cannot assign to 'id' because it is a constant or a
read-only property.(不能分配给id,因为它是常量或只读属性)
注意:只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
注意:只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let pany: Person = {
name: 'pany',
gender: 'male'
};
pany.id = 2;
// 第一处错误: 给 pany 赋值时没有给 id 赋值
// 第二处错误: 不能对 pany.id 赋值,因为它是只读的