基本类型定义
顾名思义,静态类型变量一旦声明,不可改变其类型。比如:如下代码就会报错:
let firstName: string = 'ls';
firstName = 12
上面代码中的 let firstName : string 其实就是一种类型注解(type annotation)。之所以叫做静态类型,是因为TS中的类型并不是在运行时起作用的,而是在编译成JS之前进行的检查,因此仅仅是静态类型,而非运行时的动态检查。如果检查编译后的JS,就会发现,在编译后的JS中,原来在TS中声明的变量类型都不复存在了。
其实,TS还能进行类型推断(type inference),比如,在下面代码中,一旦给变量c赋值12,TS就能推断出其类型为number:
let c = 12;
因此,在TS中,如果能够推断类型,可以不用进行类型注解,否则,必须明确声明类型。
TypeScript的七种基本类型包括:
- string
- number
- boolean
- bigint
- symbol
- null
- undefined
类型别名Type Alias
可以为类型指定一个别名,之后通过这个别名来声明类型:
type StringOrNum = string | number;
type ObjWithName = {name: string, uid: StringOrNum}
定义对象类型
除了使用基本类型外,也可以使用自定义类型来定义一个静态变量。
直接定义
这种方式相当是定义了一个匿名类型,然后直接使用:
let jessie: {
id: string,
name: string,
age: number
} = {
id: '9901',
name: 'Jessie',
age: 25
}
console.log(jessie);
使用接口来定义
interface IStudent {
id: string,
name: string,
age: number
}
function registerStudent(s: IStudent) {
console.log(s);
}
const jessie : IStudent = {
id: '9901',
name: 'Jessie',
age: 25
}
registerStudent(jessie);
运行这段代码的输出为:
{ id: '9901', name: 'Jessie', age: 25 }
使用类型定义数组
let oddNumbers : number[] = [1, 3, 5, 7, 9];
let studentNames: string[] = ['Jessie', 'Lucas'];
let undefinedArr: undefined[] = [undefined, undefined];
let mixedArr: (number | string)[] = ['Jessie', 123];
let studentObjects: {name:string, age:number}[] = [
{name: 'Jessie', age: 22},
{name: 'Lucas', age: 21}
]
对于混合型的数组,TS可以进行类型推断,比如,如下定义也是合法的:
let mixed = ['George', 25, 30, 'Paul'];
也可以把对类型的定义抽象出来,单独定义个类型,便于以后重用:
type Student = {
name: string,
age: number
};
let studentObjects2 : Student[] = [
{name: 'Jessie', age: 22},
{name: 'Lucas', age: 21}
]
当然,也可以单独定义一个类:
class Teacher {
name: string = 'Nobody';
subject: string = 'Math';
}
let teachers: Teacher[] = [
{name: 'Paul', subject: 'Math'},
{name: 'Jim', subject: 'Computing'}
]
使用元组
尽管可以使用类似这样的类型定义混合元素的数组:
let mixedArr: (number | string)[] = ['Jessie', 'Math', 28];
但由于它对其中元素只约束了可能的类型,但并未约束顺序,因此,有可能在赋值时出现逻辑错误,比如:
let mixedArr: (number | string)[] = ['Jessie', 28, 'Math'];
上面语句语法没错误,因此TS不会报错,但其逻辑上却不对了。本来期待数组中的第二个元素为subject,但这里却可以把subject和age互换。
为了解决这个问题,在TS中可以使用元组来定义数组中元素类型的准确次序:
let yearOneTeachers : [string, string, number][] = [
['Jessie', 'Math', 28],
['Lucy', 'English', 37],
['Paul', 'Computing', 55]
]
元组示例:
class StudentHelper {
static register(id: number, name: string, address: string) {
}
}
let values: [number, string, string];
values = [1, 'Lucy', '1 Fake Street'];
StudentHelper.register(...values);
xx.d.ts是什么东东?
在使用TS的时候,经常会看到类似xx.d.ts的文件,那么这种文件的作用又是什么呢?
先来看一个问题,如果我们打算使用一个旧版本的JS库,比如jQuery:
$(function() {
console.log("demo");
});
这时,在VS Code中会在 $ 下面标红,并提示:
Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`.ts(2581)
当然,此时可以通过三种方式来解决这个问题:
安装对应的类型声明
npm i -D @types/jquery
骗过TS编译器
或者,在顶部声明:
declare var $: any;
创建xx.d.ts文件
对于常用的JS库,比如jQuery,都有现成的类型声明,只需按照第一种方法安装即可。但对于不常见的第三方库,或自己项目中的传统JS库,就需要创建一个xx.d.ts文件,并在该文件中声明对应的类型。
这时,首先需要更新tsconfig.json文件:
"baseUrl": ".",
"paths": {"./node_modules/@types", "./typings/*"},
接下来创建和第三方模块同名的文件夹,并创建文件xx.d.ts:
mkdir lscoding
touch lscoding/lscoding.d.ts
lscoding.d.ts的内容类似于:
declare function f1(a: number, b: string): number
export = f1