type MyExclude<T, U> = T extends U ? never : T
type A = 'a' | 'b';// MyExclude<'a' | 'b', 'b'>
type B = 'b';
type C = A extends B ? never : A; // 'a' | 'b'
type D = MyExclude<A, B> // 'a'
在类型C中,A并不是一个泛型类型;它是一个字符串字面量的联合类型('s' | 'n' | 'q')。当你在一个条件类型中使用非泛型类型时,该条件类型不会进行分布式的处理,而是将整个类型的完整集合作为一个整体来评估条件。因此,在C中,你是在检查整个类型A是否扩展了整个类型B。由于'B'中不包含'q',所以在结果中它会被包含进来。而在类型D中,你使用了一个名为MyExclude<T, U>的泛型条件类型,并且当你将这个类型应用到类型A和B上时,它会变得具有分布性。对于联合类型A中的每一个元素,条件都会被单独地检查。所以,'s'和'n'分别被排除掉,而'q'没有被排除,从而得到的结果类型是'q'。总结来说,这种差异主要源于条件类型在应用于非泛型类型和泛型类型时的不同行为。非泛型类型不具备分布性,而泛型类型可以具有分布性,能够逐一考虑联合类型中的每一个元素。
infer
获取属性关键字 Array<string>
Array<infer U>
可以获取U:string
type myInter<T> = T extends Array<infer U> ? U : T
type A = myInter<unknown[]>; // unknown
const a: A = '1'
unknown和any
let a: unknown = 10;
a = '100';
let an: any
let b: string = an;
b = a; // 报错:unknown不能赋值给string;
any可以赋值给任何类型,unknown不可以赋值给其他类型
as & satisfies
// (as & satisfies)
// as 强制断言;
const a = { age: 100, name: 'liming' } as { name: string; age: number; sex: string }; // 即使没有也不会报错
// satisfies 是基于当前值满足的类型;
const b = { age: 100, name: 'liming' } satisfies { name: string; age: number; sex: string };
// 报错
// 类型“{ age: number; name: string; }”不满足预期类型“{ name: string; age: number; sex: string; }”。
// 类型 "{ age: number; name: string; }" 中缺少属性 "sex",但类型 "{ name: string; age: number; sex: string; }" 中需要该属性
a.sex = 'xxx'; // 不报错;
b.sex = 'xxx'; // 报错;
tsconfig.json
简介
tsconfig.json
是 TypeScript 项目的配置文件,放在项目的根目录。反过来说,如果一个目录里面有tsconfig.json
,TypeScript 就认为这是项目的根目录。
如果项目源码是 JavaScript,但是想用 TypeScript 处理,那么配置文件的名字是jsconfig.json
,它跟tsconfig
的写法是一样的。
tsconfig.json
文件主要供tsc
编译器使用,它的命令行参数--project
或-p
可以指定tsconfig.json
的位置(目录或文件皆可)。
bash
$ tsc -p ./dir
如果不指定配置文件的位置,tsc
就会在当前目录下搜索tsconfig.json
文件,如果不存在,就到上一级目录搜索,直到找到为止。
tsconfig.json
文件的格式,是一个 JSON 对象,最简单的情况可以只放置一个空对象{}
。下面是一个示例。
json
{ "compilerOptions": { "outDir": "./built", "allowJs": true, "target": "es5" }, "include": ["./src/**/*"]}
本章后面会详细介绍tsconfig.json
的各个属性,这里简单说一下,上面示例的四个属性的含义。
- include:指定哪些文件需要编译。
- allowJs:指定源目录的 JavaScript 文件是否原样拷贝到编译后的目录。
- outDir:指定编译产物存放的目录。
- target:指定编译产物的 JS 版本。
tsconfig.json
文件可以不必手写,使用 tsc 命令的--init
参数自动生成。
bash
$ tsc --init
上面命令生成的tsconfig.json
文件,里面会有一些默认配置。
你也可以使用别人预先写好的 tsconfig.json 文件,npm 的@tsconfig
名称空间下面有很多模块,都是写好的tsconfig.json
样本,比如 @tsconfig/recommended
和@tsconfig/node16
。
这些模块需要安装,以@tsconfig/deno
为例。
bash
$ npm install --save-dev @tsconfig/deno# 或者$ yarn add --dev @tsconfig/deno
安装以后,就可以在tsconfig.json
里面引用这个模块,相当于继承它的设置,然后进行扩展。
json
{ "extends": "@tsconfig/deno/tsconfig.json"}
@tsconfig
空间下包含的完整 tsconfig 文件目录,可以查看 GitHub。
tsconfig.json
的一级属性并不多,只有很少几个,但是compilerOptions
属性有很多二级属性。下面先逐一介绍一级属性,然后再介绍compilerOptions
的二级属性,按照首字母排序。
exclude
exclude
属性是一个数组,必须与include
属性一起使用,用来从编译列表中去除指定的文件。它也支持使用与include
属性相同的通配符。
typescript
{ "include": ["**/*"], "exclude": ["**/*.spec.ts"]}
extends
tsconfig.json
可以继承另一个tsconfig.json
文件的配置。如果一个项目有多个配置,可以把共同的配置写成tsconfig.base.json
,其他的配置文件继承该文件,这样便于维护和修改。
extends
属性用来指定所要继承的配置文件。它可以是本地文件。
json
{ "extends": "../tsconfig.base.json"}
如果extends
属性指定的路径不是以./
或../
开头,那么编译器将在node_modules
目录下查找指定的配置文件。
extends
属性也可以继承已发布的 npm 模块里面的 tsconfig 文件。
json
{ "extends": "@tsconfig/node12/tsconfig.json"}
extends
指定的tsconfig.json
会先加载,然后加载当前的tsconfig.json
。如果两者有重名的属性,后者会覆盖前者。
files
files
属性指定编译的文件列表,如果其中有一个文件不存在,就会报错。
它是一个数组,排在前面的文件先编译。
javascript
{ "files": ["a.ts", "b.ts"]}
该属性必须逐一列出文件,不支持文件匹配。如果文件较多,建议使用include
和exclude
属性。
include
include
属性指定所要编译的文件列表,既支持逐一列出文件,也支持通配符。文件位置相对于当前配置文件而定。
typescript
{ "include": ["src/**/*", "tests/**/*"]}
include
属性支持三种通配符。
?
:指代单个字符- :指代任意字符,不含路径分隔符
*
:指定任意目录层级。
如果不指定文件后缀名,默认包括.ts
、.tsx
和.d.ts
文件。如果打开了allowJs
,那么还包括.js
和.jsx
。
references
references
属性是一个数组,数组成员为对象,适合一个大项目由许多小项目构成的情况,用来设置需要引用的底层项目。
javascript
{ "references": [ { "path": "../pkg1" }, { "path": "../pkg2/tsconfig.json" } ]}
references
数组成员对象的path
属性,既可以是含有文件tsconfig.json
的目录,也可以直接是该文件。
与此同时,引用的底层项目的tsconfig.json
必须启用composite
属性。
javascript
{ "compilerOptions": { "composite": true }}
compileOptions
compilerOptions
属性用来定制编译行为。这个属性可以省略,这时编译器将使用默认设置。
allowJs
allowJs
允许 TypeScript 项目加载 JS 脚本。编译时,也会将 JS 文件,一起拷贝到输出目录。
json
{ "compilerOptions": { "allowJs": true }}
alwaysStrict
alwaysStrict
确保脚本以 ECMAScript 严格模式进行解析,因此脚本头部不用写"use strict"
。它的值是一个布尔值,默认为true
。
allowSyntheticDefaultImports
allowSyntheticDefaultImports
允许import
命令默认加载没有default
输出的模块。
比如,打开这个设置,就可以写import React from "react";
,而不是import * as React from "react";
。
allowUnreachableCode
allowUnreachableCode
设置是否允许存在不可能执行到的代码。它的值有三种可能。
undefined
: 默认值,编辑器显示警告。true
:忽略不可能执行到的代码。false
:编译器报错。
allowUnusedLabels
allowUnusedLabels
设置是否允许存在没有用到的代码标签(label)。它的值有三种可能。
undefined
: 默认值,编辑器显示警告。true
:忽略没有用到的代码标签。false
:编译器报错。
baseUrl
baseUrl
的值为字符串,指定 TypeScript 项目的基准目录。
由于默认是以 tsconfig.json 的位置作为基准目录,所以一般情况不需要使用该属性。
typescript
{ "compilerOptions": { "baseUrl": "./" }}
上面示例中,baseUrl
为当前目录./
。那么,当遇到下面的语句,TypeScript 将以./
为起点,寻找hello/world.ts
。
typescript
import { helloWorld } from "hello/world";
checkJs
checkJS
设置对 JS 文件同样进行类型检查。打开这个属性,也会自动打开allowJs
。它等同于在 JS 脚本的头部添加// @ts-check
命令。
json
{ "compilerOptions": { "checkJs": true }}
composite
composite
打开某些设置,使得 TypeScript 项目可以进行增量构建,往往跟incremental
属性配合使用。
declaration
declaration
设置编译时是否为每个脚本生成类型声明文件.d.ts
。
javascript
{ "compilerOptions": { "declaration": true }}
declarationDir
declarationDir
设置生成的.d.ts
文件所在的目录。
typescript
{ "compilerOptions": { "declaration": true, "declarationDir": "./types" }}
declarationMap
declarationMap
设置生成.d.ts
类型声明文件的同时,还会生成对应的 Source Map 文件。
javascript
{ "compilerOptions": { "declaration": true, "declarationMap": true }}
emitBOM
emitBOM
设置是否在编译结果的文件头添加字节顺序标志 BOM,默认值是false
。
emitDeclarationOnly
emitDeclarationOnly
设置编译后只生成.d.ts
文件,不生成.js
文件。
esModuleInterop
esModuleInterop
修复了一些 CommonJS 和 ES6 模块之间的兼容性问题。
如果module
属性为node16
或nodenext
,则esModuleInterop
默认为true
,其他情况默认为false
。
打开这个属性,使用import
命令加载 CommonJS 模块时,TypeScript 会严格检查兼容性问题是否存在。
typescript
import * as moment from "moment";moment(); // 报错
上面示例中,根据 ES6 规范,import * as moment
里面的moment
是一个对象,不能当作函数调用,所以第二行报错了。
解决方法就是改写上面的语句,改成加载默认接口。
typescript
import moment from "moment";moment(); // 不报错
打开esModuleInterop
以后,如果将上面的代码编译成 CommonJS 模块格式,就会加入一些辅助函数,保证编译后的代码行为正确。
注意,打开esModuleInterop
,将自动打开allowSyntheticDefaultImports
。
exactOptionalPropertyTypes
exactOptionalPropertyTypes
设置可选属性不能赋值为undefined
。
typescript
// 打开 exactOptionalPropertyTypesinterface MyObj { foo?: "A" | "B";}let obj: MyObj = { foo: "A" };obj.foo = undefined; // 报错
上面示例中,foo
是可选属性,打开exactOptionalPropertyTypes
以后,该属性就不能显式赋值为undefined
。
forceConsistentCasingInFileNames
forceConsistentCasingInFileNames
设置文件名是否为大小写敏感,默认为true
。
incremental
incremental
让 TypeScript 项目构建时产生文件tsbuildinfo
,从而完成增量构建。
inlineSourceMap
inlineSourceMap
设置将 SourceMap 文件写入编译后的 JS 文件中,否则会单独生成一个.js.map
文件。
inlineSources
inlineSources
设置将原始的.ts
代码嵌入编译后的 JS 中。
它要求sourceMap
或inlineSourceMap
至少打开一个。
isolatedModules
isolatedModules
设置如果当前 TypeScript 脚本作为单个模块编译,是否会因为缺少其他脚本的类型信息而报错,主要便于非官方的编译工具(比如 Babel)正确编译单个脚本。
jsx
jsx
设置如何处理.tsx
文件。它一般以下三个值。
preserve
:保持 jsx 语法不变,输出的文件名为 jsx。react
:将<div />
编译成React.createElement("div")
,输出的文件名为.js
。react-native
:保持 jsx 语法不变,输出的文件后缀名为.js
。
javascript
{ "compilerOptions": { "jsx": "preserve" }}
lib
lib
值是一个数组,描述项目需要加载的 TypeScript 内置类型描述文件,跟三斜线指令/// <reference lib="" />
作用相同。
javascript
{ "compilerOptions": { "lib": ["dom", "es2021"] }}
TypeScript 内置的类型描述文件,主要有以下一些,完整的清单可以参考 TypeScript 源码。
- ES5
- ES2015
- ES6
- ES2016
- ES7
- ES2017
- ES2018
- ES2019
- ES2020
- ES2021
- ES2022
- ESNex
- DOM
- WebWorker
- ScriptHost
listEmittedFiles
listEmittedFiles
设置编译时在终端显示,生成了哪些文件。
typescript
{ "compilerOptions": { "listEmittedFiles": true }}
listFiles
listFiles
设置编译时在终端显示,参与本次编译的文件列表。
javascript
{ "compilerOptions": { "listFiles": true }}
mapRoot
mapRoot
指定 SourceMap 文件的位置,而不是默认的生成位置。
typescript
{ "compilerOptions": { "sourceMap": true, "mapRoot": "https://my-website.com/debug/sourcemaps/" }}
module
module
指定编译产物的模块格式。它的默认值与target
属性有关,如果target
是ES3
或ES5
,它的默认值是commonjs
,否则就是ES6/ES2015
。
json
{ "compilerOptions": { "module": "commonjs" }}
它可以取以下值:none、commonjs、amd、umd、system、es6/es2015、es2020、es2022、esnext、node16、nodenext。
moduleResolution
moduleResolution
确定模块路径的算法,即如何查找模块。它可以取以下四种值。
node
:采用 Node.js 的 CommonJS 模块算法。node16
或nodenext
:采用 Node.js 的 ECMAScript 模块算法,从 TypeScript 4.7 开始支持。classic
:TypeScript 1.6 之前的算法,新项目不建议使用。
它的默认值与module
属性有关,如果module
为AMD
、UMD
、System
或ES6/ES2015
,默认值为classic
;如果module
为node16
或nodenext
,默认值为这两个值;其他情况下,默认值为Node
。
相关文章:https://juejin.cn/post/7221551421833314360#heading-33
moduleSuffixes
moduleSuffixes
指定模块的后缀名。
typescript
{ "compilerOptions": { "moduleSuffixes": [".ios", ".native", ""] }}
上面的设置使得 TypeScript 对于语句import * as foo from "./foo";
,会搜索以下脚本./foo.ios.ts
、./foo.native.ts
和./foo.ts
。
newLine
newLine
设置换行符为CRLF
(Windows)还是LF
(Linux)。
noEmit
noEmit
设置是否产生编译结果。如果不生成,TypeScript 编译就纯粹作为类型检查了。
noEmitHelpers
noEmitHelpers
设置在编译结果文件不插入 TypeScript 辅助函数,而是通过外部引入辅助函数来解决,比如 NPM 模块tslib
。
noEmitOnError
noEmitOnError
指定一旦编译报错,就不生成编译产物,默认为false
。
noFallthroughCasesInSwitch
noFallthroughCasesInSwitch
设置是否对没有break
语句(或者return
和throw
语句)的 switch 分支报错,即case
代码里面必须有终结语句(比如break
)。
noImplicitAny
noImplicitAny
设置当一个表达式没有明确的类型描述、且编译器无法推断出具体类型时,是否允许将它推断为any
类型。
它是一个布尔值,默认为true
,即只要推断出any
类型就报错。
noImplicitReturns
noImplicitReturns
设置是否要求函数任何情况下都必须返回一个值,即函数必须有return
语句。
noImplicitThis
noImplicitThis
设置如果this
被推断为any
类型是否报错。
noUnusedLocals
noUnusedLocals
设置是否允许未使用的局部变量。
noUnusedParameters
noUnusedParameters
设置是否允许未使用的函数参数。
outDir
outDir
指定编译产物的存放目录。如果不指定,编译出来的.js
文件存放在对应的.ts
文件的相同位置。
outFile
outFile
设置将所有非模块的全局文件,编译在同一个文件里面。它只有在module
属性为None
、System
、AMD
时才生效,并且不能用来打包 CommonJS 或 ES6 模块。
paths
paths
设置模块名和模块路径的映射,也就是 TypeScript 如何导入require
或imports
语句加载的模块。
paths
基于baseUrl
进行加载,所以必须同时设置后者。
typescript
{ "compilerOptions": { "baseUrl": "./", "paths": { "b": ["bar/b"] } }}
它还可以使用通配符“*”。
typescript
{ "compilerOptions": { "baseUrl": "./", "paths": { "@bar/*": ["bar/*"] } }}
preserveConstEnums
preserveConstEnums
将const enum
结构保留下来,不替换成常量值。
javascript
{ "compilerOptions": { "preserveConstEnums": true }}
pretty
pretty
设置美化输出终端的编译信息,默认为true
。
removeComments
removeComments
移除 TypeScript 脚本里面的注释,默认为false
。
resolveJsonModule
resolveJsonModule
允许 import 命令导入 JSON 文件。
rootDir
rootDir
设置源码脚本所在的目录,主要跟编译后的脚本结构有关。rootDir
对应目录下的所有脚本,会成为输出目录里面的顶层脚本。
rootDirs
rootDirs
把多个不同目录,合并成一个目虚拟目录,便于模块定位。
typescript
{ "compilerOptions": { "rootDirs": ["bar", "foo"] }}
上面示例中,rootDirs
将bar
和foo
组成一个虚拟目录。
sourceMap
sourceMap
设置编译时是否生成 SourceMap 文件。
sourceRoot
sourceRoot
在 SourceMap 里面设置 TypeScript 源文件的位置。
typescript
{ "compilerOptions": { "sourceMap": true, "sourceRoot": "https://my-website.com/debug/source/" }}
strict
strict
用来打开 TypeScript 的严格检查。它的值是一个布尔值,默认是关闭的。
typescript
{ "compilerOptions": { "strict": true }}
这个设置相当于同时打开以下的一系列设置。
- alwaysStrict
- strictNullChecks
- strictBindCallApply
- strictFunctionTypes
- strictPropertyInitialization
- noImplicitAny
- noImplicitThis
- useUnknownInCatchVaria
打开strict
的时候,允许单独关闭其中一项。
json
{ "compilerOptions": { "strict": true, "alwaysStrict": false }}
strictBindCallApply
strictBindCallApply
设置是否对函数的call()
、bind()
、apply()
这三个方法进行类型检查。
如果不打开strictBindCallApply
编译选项,编译器不会对以三个方法进行类型检查,参数类型都是any
,传入任何参数都不会产生编译错误。
typescript
function fn(x: string) { return parseInt(x);}// strictBindCallApply:falseconst n = fn.call(undefined, false);// 以上不报错
strictFunctionTypes
strictFunctionTypes
允许对函数更严格的参数检查。具体来说,如果函数 B 的参数是函数 A 参数的子类型,那么函数 B 不能替代函数 A。
typescript
function fn(x: string) { console.log("Hello, " + x.toLowerCase());}type StringOrNumberFunc = (ns: string | number) => void;// 打开 strictFunctionTypes,下面代码会报错let func: StringOrNumberFunc = fn;
上面示例中,函数fn()
的参数是StringOrNumberFunc
参数的子集,因此fn
不能替代StringOrNumberFunc
。
strictNullChecks
strictNullChecks
设置对null
和undefined
进行严格类型检查。如果打开strict
属性,这一项就会自动设为true
,否则为false
。
bash
let value:string;// strictNullChecks:false// 下面语句不报错value = null;
它可以理解成只要打开,就需要显式检查null
或undefined
。
typescript
function doSomething(x: string | null) { if (x === null) { // do nothing } else { console.log("Hello, " + x.toUpperCase()); }}
strictPropertyInitialization
strictPropertyInitialization
设置类的实例属性都必须初始化,包括以下几种情况。
- 设为
undefined
类型 - 显式初始化
- 构造函数中赋值
注意,使用该属性的同时,必须打开strictNullChecks
。
typescript
// strictPropertyInitialization:trueclass User { // 报错,属性 username 没有初始化 username: string;}// 解决方法一class User { username = "张三";}// 解决方法二class User { username: string | undefined;}// 解决方法三class User { username: string; constructor(username: string) { this.username = username; }}// 或者class User { constructor(public username: string) {}}// 解决方法四:赋值断言class User { username!: string; constructor(username: string) { this.initialize(username); } private initialize(username: string) { this.username = username; }}
suppressExcessPropertyErrors
suppressExcessPropertyErrors
关闭对象字面量的多余参数的报错。
target
target
指定编译出来的 JavaScript 代码的 ECMAScript 版本,比如es2021
,默认是es3
。
它可以取以下值。
- es3
- es5
- es6/es2015
- es2016
- es2017
- es2018
- es2019
- es2020
- es2021
- es2022
- esnext
注意,如果编译的目标版本过老,比如"target": "es3"
,有些语法可能无法编译,tsc
命令会报错。
traceResolution
traceResolution
设置编译时,在终端输出模块解析的具体步骤。
typescript
{ "compilerOptions": { "traceResolution": true }}
typeRoots
typeRoots
设置类型模块所在的目录,默认是node_modules/@types
。
typescript
{ "compilerOptions": { "typeRoots": ["./typings", "./vendor/types"] }}
types
types
设置typeRoots
目录下需要包括在编译之中的类型模块。默认情况下,该目录下的所有类型模块,都会自动包括在编译之中。
typescript
{ "compilerOptions": { "types": ["node", "jest", "express"] }}
useUnknownInCatchVariables
useUnknownInCatchVariables
设置catch
语句捕获的try
抛出的返回值类型,从any
变成unknown
。
typescript
try { someExternalFunction();} catch (err) { err; // 类型 any}
上面示例中,默认情况下,catch
语句的参数err
类型是any
,即可以是任何值。
打开useUnknownInCatchVariables
以后,err
的类型抛出的错误将是unknown
类型。这带来的变化就是使用err
之前,必须缩小它的类型,否则会报错。
typescript
try { someExternalFunction();} catch (err) { if (err instanceof Error) { console.log(err.message); }}
参考链接
命令行参数
tsc 的命令行参数,大部分与 tsconfig.json 的属性一一对应。
下面只是按照首字母排序,简单罗列出主要的一些参数,详细解释可以参考《tsconfig.json 配置文件》一章。
-all
:输出所有可用的参数。-allowJs
:允许 TS 脚本加载 JS 模块,编译时将 JS 一起拷贝到输出目录。-allowUnreachableCode
:如果 TS 脚本有不可能运行到的代码,不报错。-allowUnusedLabels
:如果 TS 脚本有没有用到的标签,不报错。-alwaysStrict
:总是在编译产物的头部添加use strict
。-baseUrl
:指定非相对位置的模块定位的基准 URL。-build
:启用增量编译。-checkJs
:对 JS 脚本进行类型检查。-declaration
:为 TS 脚本生成一个类型生成文件。-declarationDir
:指定生成的类型声明文件的所在目录。-declarationMap
:为.d.ts
文件生成 Source有效-diagnostics
:构建后输出编译性能信息。- 有效
-emitDeclarationOnly
:只编译输出类型声明文件,不输出 JS 文件。-esModuleInterop
:更容易使用 import 命令加载 CommonJS 模块。-exactOptionalPropertyTypes
:不允许将可选属性设置为undefined
。-experimentalDecorators
:支持早期的装饰器语法。-explainFiles
:输出进行编译的文件信息。-forceConsistentCasingInFileNames
:文件名大小写敏感,默认打开。-help
:输出帮助信息。-importHelpers
:从外部库(比如 tslib)输入辅助函数。-incremental
:启用增量构建。-init
:在当前目录创建一个全新的tsconfig.json
文件,里面是预设的设置。-inlineSourceMap
:SourceMap 信息嵌入 JS 文件,而不是生成独立的.js.map
文件。-inlineSources
:将 TypeScript 源码作为 SourceMap 嵌入编译出来的 JS 文件。-isolatedModules
:确保每个模块能够独立编译,不依赖其他输入的模块。-jsx
:设置如何处理 JSX 文件。-lib
:设置目标环境需要哪些内置库的类型描述。-listEmittedFiles
:编译后输出编译产物的文件名。-listFiles
:编译过程中,列出读取的文件名。-listFilesOnly
:列出编译所要处理的文件,然后停止编译。-locale
:指定编译时输出的语言,不影响编译结果。-mapRoot
:指定 SourceMap 文件的位置。-module
:指定编译生成的模块格式。-moduleResolution
:指定如何根据模块名找到模块的位置。-moduleSuffixes
:指定模块文件的后缀名。-newLine
:指定编译产物的换行符,可以设为crlf
或者lf
。-noEmit
:不生成编译产物,只进行类型检查。-noEmitHelpers
:不在编译产物中加入辅助函数。-noEmitOnError
:一旦报错,就停止编译,没有编译产物。-noFallthroughCasesInSwitch
:Switch 结构的case
分支必须有终止语句(比如break
)。-noImplicitAny
:类型推断只要为any
类型就报错。-noImplicitReturns
:函数内部没有显式返回语句(比如return
)就报错。-noImplicitThis
:如果this
关键字是any
类型,就报错。-noImplicitUseStrict
:编译产生的 JS 文件头部不添加use strict
语句。-noResolve
:不进行模块定位,除非该模块是由命令行传入。-noUnusedLocals
:如果有未使用的局部变量就报错。-noUnusedParameters
:如果有未使用的函数参数就报错。-outDir
:指定编译产物的存放目录。-outFile
:所有编译产物打包成一个指定文件。-preserveConstEnums
:不将const enum
结构在生成的代码中,替换成常量。-preserveWatchOutput
: watch 模式下不清屏。-pretty
:美化显示编译时的终端输出。这是默认值,但是可以关闭-pretty false
。-project
(或者p
):指定编译配置文件,或者该文件所在的目录。-removeComments
:编译结果中移除代码注释。-resolveJsonModule
:允许加载 JSON 文件。-rootDir
:指定加载文件所在的根目录,该目录里面的目录结构会被复制到输出目录。-rootDirs
:允许模块定位时,多个目录被当成一个虚拟目录。-skipDefaultLibCheck
:跳过 TypeScript 内置类型声明文件的类型检查。-skipLibCheck
:跳过.d.ts
类型声明文件的类型检查。这样可以加快编译速度。-showConfig
:终端输出编译配置信息,而不进行配置。-sourcemap
:为编译产生的 JS 文件生成 SourceMap 文件(.map 文件)。-sourceRoot
:指定 SourceMap 文件里面的 TypeScript 源码根目录位置。-strict
:打开 TypeScript 严格检查模式。-strictBindCallApply
:bind, call、apply 这三个函数的类型,匹配原始函数。-strictFunctionTypes
:如果函数 B 的参数是函数 A 参数的子类型,那么函数 B 不能替代函数 A。-strictNullChecks
:对null
和undefined
进行严格类型检查。-strictPropertyInitialization
:类的属性必须进行初始值,但是允许在构造函数里面赋值。-suppressExcessPropertyErrors
:关闭对象字面量的多余参数的报错。-target
:指定编译出来的 JS 代码的版本,TypeScirpt 还会在编译时自动加入对应的库类型声明文件。-traceResolution
:编译时在终端输出模块解析(moduleResolution)的具体步骤。-typeRoots
:设置类型模块所在的目录,替代默认的node_modules/@types
。-types
:设置typeRoots
目录下需要包括在编译之中的类型模块。-version
:终端输出 tsc 的版本号。-watch
(或者w
):进入观察模式,只要文件有修改,就会自动重新编译。
全局类型声明
- TypeScript 对文件的两种处理方式:
- 脚本文件:没有
import
/export
的文件,视为全局作用域,其中的声明会直接添加到全局。 - 模块文件:包含
import
/export
的文件,视为独立模块,其中的declare global
用于扩展全局作用域(而非直接声明全局)。
- 脚本文件:没有
有效
import type { Ref } from 'vue';
declare global {
declare type Nullable<T> = T | null;
declare type RefType<T> = Ref<T | null>;
}
文件不包含import
时,需要使用export{}
, 表明为独立模块才会在全局生效
declare global {
declare type Nullable<T> = T | null;
declare type RefType<T> = Ref<T | null>;
}
export {}