目录
- 前言
- 1、基元类型
- 2、数组
- 3、any
- 4、函数
- 5、对象
- 6、unknown
前言
在学习TypeScript之前我们需要先全局安装tsc TypeScript 编译器。
npm在项目根目录下运行:
tsc -init此时项目根目录下会生成一个配置文件 tsconfig.json ,这里给出我使用的配置:
{
"compilerOptions": {
/* TS编译成JS的版本*/
"target": "es6",
/* 入口文件:指定源文件中的根文件夹。 */
"rootDir": "./src",
/* 编译出口文件:指定输出文件夹。 */
"outDir": "./dist",
/* 严格模式 */
"strict": true,
}
}注意:我们实用TypeScript的目的就是检验代码并纠错,尽量使自己的代码变得足够规范,所以建议应始终使用"strict": true
1、基元类型
JavaScript有三个非常常用的类型: string , number ,和boolean 。
它们在 TypeScript 中都有对应的类型,并且这些名称与在 JavaScript 应用typeof 返回的类型的名称相同:
-
string 表示字符串值,如"Hello, world" -
number 表示数字值,如 42 。JavaScript 没有一个特殊的整数运行时值,所以没有等价于int 或float 类型, 一切都只是number -
boolean 只有两个值true 和false
类型名称String , Number , 和Boolean (以大写字母开头)是合法的,但指的是一些很少出现在
代码中的特殊内置类型。对于类型,始终使用string , number , 或boolean 。
在TypeScript中,当你使用const , var , 或let 时可以直接在变量后加上类型注释: type就可以显式指定变量的类型为type:
var str: string = "hello,world";
const num: number = 42;
let boo: boolean = true;
但是,在大多数情况下,这不是必需的。只要有可能,TypeScript 就会尝试自动推断代码中的类型。例如,变量的类型是根据其初始化器的类型推断出来的:
// 不需要类型定义--“myName”自动推断为类型“string”
let myName = "AiLjx";
对于已经声明类型的变量,对其赋值时只能赋予其相同类型的数据,否者TypeScript将会抛出错误:

2、数组
指定数组的类型可以使用ItemType[]或者Array<ItemType>,ItemType指数组元素的类型,
Array<ItemType>声明类型的方式使用了TypeScript的泛型语法,对于泛型,之后我会出单独的一篇博文对其详细的介绍
const arr1:number[]=[1,2,3]
const arr2:string[]=['1','2','3']
同样的,对已经指定类型的数组赋不同类型的值,或向其添加不同类型的数据时,TypeScript将会抛出错误:

3、any
TypeScript 还有一个特殊类型 any ,当你不希望某个特定值导致类型检查错误时,可以使用它。
当一个值的类型是any 时,可以访问它的任何属性,将它分配给任何类型的值,或者几乎任何其他语法上的东西都合法的:
src/01-type.ts:
let obj: any = { x: 0 };
// 以下代码行都不会抛出编译器错误。
// 使用'any'将禁用所有进一步的类型检查
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;
但在运行环境下执行代码可能是错误的:

进入到 dist 目录中,在 node 环境里运行代码,果然报错了。
当你不想写出长类型只是为了让 TypeScript 相信特定的代码行没问题时, any 类型很有用。
但万万不可大量使用any类型,因为any 没有进行类型检查,使用它就相当于在使用原生JS,失去了TS的意义!!!
4、函数
TypeScript 允许您指定函数的输入和输出值的类型。
- 参数类型注释
声明函数时,可以在每个参数后添加类型注解,以声明函数接受的参数类型。参数类型注释位于参数名称之后:
// 参数类型定义
function getName(name: string) {
console.log("Hello, " + name);
}
这里指定了getName函数接收一个string类型的参数,当参数类型不匹配时将抛出错误:

即使您的参数上没有类型注释,TypeScript 仍会检查您是否传递了正确数量的参数!
- 返回类型注释
返回类型注释出现在参数列表之后,其指定了函数返回值的类型:
function getName(name: string): string {
console.log("Hello, " + name);
return "Hello, " + name;
}
这里对getName函数指定了其返回值是string类型,当函数无返回值或返回值不是string类型时将抛出错误:

与变量类型注释非常相似,通常不需要返回类型注释,因为 TypeScript 会根据其return 语句推断函数的返回类型。上面例子中的类型注释不会改变任何东西。某些代码库会出于文档目的明确指定返回类型,以防止意外更改或仅出于个人偏好。
- 匿名函数
匿名函数与函数声明有点不同。当一个函数出现在 TypeScript 可以确定它将如何被调用的地方时,该函数的参数会自动指定类型。

即使参数s 没有类型注释,TypeScript 也会使用forEach 函数的类型,以及数组的推断类型来确定s 的类型。这个过程称为上下文类型,因为函数发生在其中的上下文通知它应该具有什么类型。
与推理规则类似,你不需要明确了解这是如何发生的,但了解它的机制确实可以帮助你注意何时不需要类型注释。
从这里我们就能看出TypeScript的强大之处,它不仅能够自动推断类型并发现错误,还能提示你错误的地方,以及修复建议,配合VS code编译器还能实现快速修复:

5、对象
除了string , number , boolean 类型(又称基元类型)外,你将遇到的最常见的类型是对象类型。
这指的是任何带有属性的 JavaScript 值,几乎是所有属性!要定义对象类型,我们只需列出其属性及其类型。
let obj: { x: number; y: number } = { x: 1, y: 2 };
对于指定类型的对象其值不符合指定的类型时抛出错误:

- 可选属性
在指定的类型属性名后加上一个?,可以指定该属性为可选属性:
let obj2: { x?: number; y: number } = {
y: 2, // x 是可选属性,对象内不含x属性时将不再抛出错误
};
不能直接对可选属性进行操作,不然就会抛出错误:

这很好理解,因为可选属性没有限制用户必传,如果访问一个不存在的属性,将获得值undefined ,此时对其操作TypeScript就会抛出错误提醒你。
正确的做法:
function ObjFn(obj: { x?: number; y: number }) {
console.log(obj.y++);
if (obj.x) { // 先判断可选属性是否存在
console.log(obj.x++);
}
}
6、unknown
与 any 类型类似,可以设置任何的类型值,随后可以更改类型,但unknown要比any更加安全,看个例子:
let a: any = "Ailjx";
a = [];
a.push("0");
上面代码在编译与运行时都是正常的,但是当我们手误写错了push方法后你就会发现问题所在:
let a: any = "Ailjx";
a = [];
a.psh("0");
这段代码在编译时不会报错,只会在运行时报错,这就失去了TypeScript在编译时检查错误的功能,在项目比较大时,参与的人多时,就很难避免这样类似的问题,因此unknown 类型出现了:

虽然我们将其类型更改为数组类型,但是编译器认为其依旧是unknown类型,该类型没有push方法,就会报错,除非我们先判断类型:
let a: unknown = "Ailjx";
a = [];
if (a instanceof Array) {
a.push("0");
}
这样代码就没问题了,这时如果你push方法写错了,编译器就会报错提示你了:

虽然有些麻烦,但是相比 any 类型说,更加安全,在代码编译期间,就能帮我们发现由于类型造成的问题,因此在大多的场景,建议使用 unknown 类型替代 any。










