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 {}