tsconfig.json
- compilerOptions
target
默认:使用哪种js标准进行编译
ES3
参数:es3
es5
es6/es2015
es2016
es2017
es2018
es2019
es2020
es2021
es2022
esnext
lib
库(数组配置): 当需要ts编译的脚本在浏览器上运行时,会有
document
console
等浏览器的默认方法, 可以为他配置 ‘dom’ 参数。
参数 | 描述 |
---|---|
ES5 | 所有 ES3 和 ES5 功能的核心定义 |
ES2015 | ES2015(也称为 ES6)中可用的其他 API - array.find、Promise、Proxy、Symbol、Map、Set、Reflect等。 |
ES6 | “ES2015”的别名 |
ES2016 | ES2016 中可用的其他 API -array.include等。 |
ES7 | “ES2016”的别名 |
ES2017 | ES2017 中可用的其他 API - Object.entries, Object.values, Atomics, SharedArrayBuffer, date.formatToParts, 类型数组等。 |
ES2018 | ES2018 中可用的其他 API -async可迭代、promise.finally、Intl.PluralRules、regexp.groups等。 |
ES2019 | ES2019 中可用的其他 API - array.flat, array.flatMap, Object.fromEntries, string.trimStart,string.trimEnd等。 |
ES2020 | ES2020 中可用的其他 API -string.matchAll等。 |
ES2021 | ES2021 中可用的其他 API -promise.any等string.replaceAll。 |
ESNext | ESNext 中可用的其他 API - 这会随着 JavaScript 规范的发展而变化 |
DOM | DOM定义 - window,document等。 |
WebWorker | WebWorker上下文中可用的 API |
ScriptHost | 适用于Windows 脚本托管系统的 API |
module
、moduleResolution
如module: 设置程序的模块系统(当程序进行模块化引用脚本时,把程序编译成哪种模式)
moduleResolution: 指定模块解析策略
compilerOptions.module = 'none'
、compilerOptions.moduleResolution = 'node'
/* 编译前 */
// modules/index.ts
export default {
name: '张三',
desc: '法外狂徒'
}
// app.ts
import who from './index';
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getUserInfo() {
console.log(`${this.name} - ${this.age}`);
}
sayWho() {
console.log(`${who.name} - ${who.desc}`)
}
}
const person = new Person('Person', 25);
person.getUserInfo();
person.sayWho();
/* 编译后 */
// modules/index.d.js
"use strict";
Object.defineProperty(exports, "__esModule", {value: true});
exports.default = {
name: '张三',
desc: '法外狂徒'
};
// app.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : {"default": mod};
};
Object.defineProperty(exports, "__esModule", {value: true});
const modules_1 = __importDefault(require("./index"));
class Person {
name;
age;
constructor(name, age) {
this.name = name;
this.age = age;
}
getUserInfo() {
console.log(`${this.name} - ${this.age}`);
}
sayWho() {
console.log(`${modules_1.default.name} - ${modules_1.default.desc}`);
}
}
const person = new Person('Person', 25);
person.getUserInfo();
person.sayWho();
sourceMap
为生成的JavaScript文件创建源映射文件(
xxx.js.map
)
resolveJsonModule
是否允许导入带有“.json”扩展名的模块(需要
module
为CommonJS
类型)
isolatedModules
确保每个文件都可以安全传输,而不依赖于其他导入
forceConsistentCasingInFileNames
区分大小写
strict
严格模式
esModuleInterop
提供两个helper函数
__importStar
和__importDefault
分别处理import * as
和import default
。
skipLibCheck
示例跳过
声明文件
的类型检查(跳过类型为.d.ts
的所有文件)。这可以在编译期间节省时间,但会牺牲类型系统的准确性
{
"compilerOptions": {
"target": "esnext",
"lib": [
"esnext",
"dom"
],
"module": "CommonJS",
"moduleResolution": "node",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
数据类型 及 部分 *** 作
interface IData {
str: string; // 字符串
num: number; // 数字
bool: boolean; // 布尔
n?: null; // null
un?: undefined; // undefined
arr: any[]; // 泛型数组
list: Array<any>; // 泛型数组
obj1: object; // 对象
obj2: object; // 对象
func: Function; // 函数
data: any; // 泛型
str_num: string | number; // 字符串或数字
un_know: unknown;
}
export class Data {
_str: string;
_num: number;
_bool: boolean;
_arr: any[];
_list: Array<any>;
_obj1: object;
_obj2: object;
_data: any;
_func: Function;
_str_num: string | number;
_un_know: unknown;
constructor({str, num, bool, arr, list, obj1, obj2, func, data, str_num, un_know}: IData) {
this._str = str;
this._num = num;
this._bool = bool;
this._arr = arr;
this._list = list;
this._obj1 = obj1;
this._obj2 = obj2;
this._func = func;
this._data = data;
this._str_num = typeof str_num === "string" ? str_num.toUpperCase() : str_num;
this._un_know = un_know;
}
getData() {
for (const key in this) {
console.log(key, this[key]);
}
}
}
const data = new Data({
str: '张三',
num: 18,
bool: true,
arr: [],
list: ['A', 123],
obj1: {},
obj2: [{name: 'Person'}],
func: () => 123,
data: {},
str_num: '123abc',
un_know: [123]
});
data.getData();
type interface 区别
type 不可重复定义, interface 可重复定义,重复定义类型合并
方式
type ZhanSan = {
name: string;
desc: string;
}
// 以下代码报错
// type ZhanSan = {
// age: number;
// }
interface Person {
name: string;
}
interface Person {
age: number;
}
export class Person {
constructor(zs: ZhanSan, lee: Person) {
console.log(zs, lee)
}
}
new Person({name: '张三', desc: '法外狂徒'}, {name: 'Person', age: 25});
扩展类型
方式
// type
type Animal = {
name: string;
}
type Bear = Animal & {
age: number;
}
const bear: Bear = {
name: '熊',
age: 1
}
// interface
interface Animal {
name: string;
}
interface Bear extends Animal {
age: number;
}
const bear: Bear = {
name: '熊',
age: 1
}
类型断言(unknown 不知道什么类型)
export class Person {
constructor(name: string) {
console.log(name)
}
}
let name: unknown;
new Person(name as string);
new Person(<string>name);
文字类型
export const getUserInfo = (name: string, status: 'left' | 'right' | 'center') => {
console.log(`${name} - ${status}`);
}
getUserInfo('Person', 'left');
报错:Argument of type ‘string’ is not assignable to parameter of type ‘“right” | “left” | “center”’
解决方法如下:
const data = {
name: 'Person',
status: 'right'
} as const;
export const getUserInfo = (name: string, status: 'left' | 'right' | 'center') => {
console.log(`${name} - ${status}`);
}
getUserInfo(data.name, data.status);
const data = {
name: 'Person',
status: 'right' as 'right'
};
export const getUserInfo = (name: string, status: 'left' | 'right' | 'center') => {
console.log(`${name} - ${status}`);
}
getUserInfo(data.name, data.status);
const data = {
name: 'Person',
status: 'right'
};
export const getUserInfo = (name: string, status: 'left' | 'right' | 'center') => {
console.log(`${name} - ${status}`);
}
getUserInfo(data.name, data.status as 'right');
枚举
// 编译前
export enum Direction {
Up = 1,
Right,
Down,
Left
}
console.log(Direction.Up)
// 编译后
"use strict";
Object.defineProperty(exports, "__esModule", {value: true});
exports.Direction = void 0;
var Direction;
(function (Direction) {
Direction[Direction["Up"] = 1] = "Up";
Direction[Direction["Right"] = 2] = "Right";
Direction[Direction["Down"] = 3] = "Down";
Direction[Direction["Left"] = 4] = "Left";
})(Direction = exports.Direction || (exports.Direction = {}));
console.log(Direction.Up);
//# sourceMappingURL=app.js.map
BigInt、Symbol
const a: bigint = BigInt(100);
const b: bigint = 100n;
console.log(a, b, a == b, a === b); // 100n 100n true true
const c: Symbol = Symbol('name');
const d: Symbol = Symbol('name');
console.log(c, d, c == d, c === d); // Symbol(name) Symbol(name) false false
in
type Person = {
name: string;
}
interface Animal {
name: string;
age: number
}
interface Other {
name?: string;
func: () => void;
}
const funA = (xxx: Person | Animal) => {
console.log('name', 'name' in xxx);
console.log('age', 'age' in xxx);
}
funA({name: 'Person', age: 25}); // name true ; age true ;
const funB = (xxx: Person | Animal | Other) => {
console.log('name', 'name' in xxx);
console.log('age', 'age' in xxx);
console.log('func', 'func' in xxx);
}
funB({name: 'Dog', age: 2, func: () => 'Person'}); // name true ; age true ; func true ;
instanceof
class Person {
private _name: string;
constructor(name: string) {
this._name = name;
}
}
const person: Person = new Person('Person');
console.log(person instanceof Person); // true
const obj: object = new Object({_name: 'Person'});
console.log(obj instanceof Person); // false
类型谓语
pet is Fish
type Fish = {
swim: () => void
};
type Bird = {
fly: () => void
}
// 判断传参是否为Fish类型
function isFish(pet: Fish | Bird): pet is Fish {
console.log(!!(pet as Fish).swim);
return !!(pet as Fish).swim;
}
isFish({
swim: () => {
}
}); // true
isFish({
fly: () => {
}
}); // false
never类型 (不存在状态)
const func = (data: string | number | boolean) => {
switch (typeof data) {
case 'string':
return 'string';
case 'number':
return 'number';
case 'boolean':
return 'boolean';
default:
const _data: never = data;
return _data;
}
}
let data: any; // 定义一个泛型的变量
console.log(func(data as number));
调用签名
type Person = {
fullName: string;
(age: number): number;
say: () => string;
}
const func = (person: Person) => {
console.log(`${person.fullName} - ${person(25)} ; ${person.say()}`);
}
function person(age: number): number {
return age;
}
person.fullName = 'Person';
person.say = (): string => `张三 - 18`;
func(person); // Person - 25 ; 张三 - 18
构造签名
interface Point {
x: number;
y: number;
say: () => object;
}
interface PointConstructor {
new(x: number, y: number): Point;
}
class Point2D implements Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
say(): object {
const data = {x: this.x, y: this.y};
console.log(data);
return data;
}
}
const func = (pointConstructor: PointConstructor) => {
new pointConstructor(1, 2).say();
}
func(Point2D);
限制泛型条件
function maxListCount<T extends { length: number }>(a: T, b: T): number {
return a.length > b.length ? a.length : b.length;
}
console.log(maxListCount({length: 2}, [1, 2, 3, 4])); // 4
限制泛型返回值
// 以下代码报错
function maxListData<T extends { length: number }>(a: T, b: T): T {
return a.length > b.length ? a : {length: 10}; // 报错: '{length: 10}' 不是定义的泛型T
}
// 以下代码正确
function maxListData<T extends { length: number }>(a: T, b: T): T {
return a.length > b.length ? a : b;
}
console.log(maxListData({length: 10}, [1, 2, 3, 4])); // { length: 10 }
console.log(maxListData<string[] | number[]>(['1', '2'], [1, 2, 3, 4])); // [ 1, 2, 3, 4 ]
可选参数、默认参数
const funA = (name?: string) => console.log(name);
funA(); // undefined
funA('Person'); // Person
const funB = (name: string = 'Person') => console.log(name);
funB(); // Person
funB('Tom'); // Tom
索引签名
export {}
interface Person {
[index: number]: string | number;
[props: string]: string | number;
}
const person: Person = {
0: 'PLee',
name: 'Person',
age: 25
}
console.log(person);
interface Person<T> {
[index: number]: T;
[props: string]: T;
}
const person: Person<string | number> = {
0: 'PLee',
name: 'Person',
age: 25,
}
console.log(person)
class Person {
[props: string]: number | ((s: string) => boolean);
// error 不符合索引签名
// name: string = 'Person';
// ok
age: number = 25;
// ok
fun() {
return true
}
// error 不符合索引签名
// fun(){
// return 1;
// }
// 构造函数不受影响
constructor() {
}
}
泛型类
class Person<T> {
data: T;
constructor(data: T) {
this.data = data;
console.log(this.data);
}
}
new Person<string>('abc');
keyof
type Point = {
x: number,
y: number
}
type P = keyof Point;
// const p: P = 'abc'; // 报错 p只能是 'x' 或者 'y'
const p: P = Math.random() > 0.5 ? 'x' : 'y';
console.log(p);
function func<T, K extends keyof T>(obj: T, key: K) {
console.log(obj[key])
}
// func({name: 'Person'}, 'abc'); // 报错 在泛型T中找不到abc,泛型K只能是'name'
func({name: 'Person'}, 'name');
func<object, never>({name: 'Person'}, <never>'name');
ReturnType、typeof
type Func = () => string[];
type Person = ReturnType<Func>;
const person: Person = ['Person']; // Func的返回类型是string[],那么定义的person的最终返回类型就应该是string[]
function funA(): string[] {
return ['Person']
}
// 需求: 想要定义一个类型是funA的返回类型
// type Users = ReturnType; // 报错: funA不是一个类型,这里需要的是一个类型
type Users = ReturnType<typeof funA>;
const users: Users = ['Person'];
索引访问类型
type Person = {
name: string,
age: number
}
type Num = Person['age'];
type StrNum1 = Person['name' | 'age'];
type StrNum2 = Person[keyof Person];
const List = [
{name: 'Person', age: 25},
{name: '张三', desc: '法外狂徒'},
{name: ['张三'], desc: '法外狂徒'},
]
type Name = typeof List[number]['name']; // 查找到的是 数组中每个元素下name的值类型
type Age = typeof List[number]['age'];
type Desc = typeof List[number]['desc'];
// const name1: Name = 1; // error
const name2: Name = 'abc'; // ok
const name3: Name = ['1']; // ok
条件类型
interface Animal {
name: string;
}
interface Dog extends Animal {
woof(): void;
}
// Example1 最终返回为number
type Example1 = Dog extends Animal ? number : string;
// Example1 最终返回为string
type Example2 = RegExp extends Animal ? number : string;
条件类型的应用
interface IdLabel {
id: number;
}
interface NameLabel {
name: string;
}
// 重载方式
function createLabel1(id: number): IdLabel;
function createLabel1(name: string): NameLabel;
function createLabel1(idOrName: number | string): IdLabel | NameLabel;
function createLabel1(idOrName: number | string): IdLabel | NameLabel {
throw '';
}
// 条件类型判断方式
type IdOrName<T extends number | string> = T extends number ? IdLabel : NameLabel
function createLabel2<T extends number | string>(idOrName: T): IdOrName<T> {
throw '';
}
条件类型约束
type MessageOf<T> = T extends { message: unknown } ? T['message'] : never;
type Email = {
message: string;
}
// Example1 最终类型为string
type Example1 = MessageOf<Email>;
const str: Example1 = 'abc';
// Example1 最终类型为never
type Example2 = MessageOf<number>;
const ex2: Example2 = 'err' as never;
infer
在条件类型表达式中,可以在 extends 条件语句中使用 infer 关键字来声明一个待推断的类型变量。
type Flatten<T> = T extends infer U ? U : never;
const num: Flatten<string | number> = 123;
const str: Flatten<string | number> = 'abc';
type Flatten<T> = T extends Array<infer U> ? U : never;
const num1: Flatten<[string, number]> = 123;
const num2: Flatten<[number]> = 123;
const str1: Flatten<[string, number]> = 'abc';
const str2: Flatten<[string]> = 'abc';
const data: Flatten<string | number> = 'a' as never; // 推断不出来所以是never
分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
// StrOrNumList 最终返回类型为 string[] | number[]
type StrOrNumList = ToArray<string | number>;
const list: StrOrNumList = Math.random() > 0.5 ? [1, 2, 3] : ['a', 'b', 'c'];
type ToArray<T> = [T] extends [any] ? T[] : never;
// StrOrNumList 最终返回类型为 (string | number)[]
type StrOrNumList = ToArray<string | number>;
const list: StrOrNumList = [1, 2, 'a', 'b'];
继承类的执行顺序
1、基类的字段被初始化 Person
2、基类的构造函数运行 Person
3、派生类的字段被初始化 Person
4、派生类的构造函数运行 Person
class Person {
name: string;
constructor(name: string) {
this.name = name;
console.log(this.name); // ProsperLee
}
}
class Person extends Person {
name: string = 'Person';
constructor(name: string) {
super(name);
console.log(this.name) // Person
}
}
const lee = new Person('ProsperLee');
console.log(lee); // Person { name: 'Person' }
// 'ProsperLee' ---> 'Person' ---> Person { name: 'Person' }
继承js中的内置类型
class MsgError extends Error {
constructor(msg: string) {
super(msg);
// 解决低版本下找不到msgError.sayMsg方法运行报错问题,如在target为es5时
Object.setPrototypeOf(this, MsgError.prototype);
}
sayMsg() {
console.log(this.message);
}
}
const msgError = new MsgError('ProsperLee');
msgError.sayMsg();
public、protected、private
public 公开的,任何对象内均可访问
protected 受保护的,类及子类能够访问
private 私有的,当前类内能够访问
const Person = class<T> {
constructor(public a: T, protected b: T[], private c: number) {
this.a = a;
this.b = b;
this.c = c;
}
}
const person = new Person<string>('Person', ['a', 'b'], 10);
console.log(person.a);
// console.log(person.b); // Property 'b' is protected and only accessible within class 'Person ' and its subclasses.
// console.log(person.c); // Property 'c' is private and only accessible within class 'Person '.
类里的 static 区块 (#data
仅供内部使用)
class Perosn {
static #data = 'Person123';
get data() {
return Perosn.#data;
}
// 默认会执行
static {
Perosn.#data += '!@#';
}
static sayData() {
console.log(Perosn.#data);
}
sayData() {
console.log(Perosn.#data);
}
}
// Property '#data' is not accessible outside class 'Perosn' because it has a private identifier.
// 属性“#data”在类“Perosn”之外不可访问,因为它有一个私有标识符。
// Perosn.#data = 'Person';
Perosn.sayData(); // Person123!@#
const person = new Perosn();
console.log(person.data); // Person123!@# (调用的get方法)
person.sayData(); // Person123!@# (调用的sayData方法)
泛型类
class Perosn<T> {
_data: T;
constructor(data: T) {
this._data = data;
}
}
const person = new Perosn<number>(123);
console.log(person._data); // 123
const person1 = new Perosn({name: 'Person'});
console.log(person1._data); // { name: 'Person' }
const person2 = new Perosn('Person');
console.log(person2._data); // Person
类中的this指向
class Person {
data: string = 'Person';
getData() {
return this.data;
}
}
const lee = new Person();
const tom = {
data: 'Tom',
getData: lee.getData
}
console.log(lee.getData()); // Person
console.log(tom.getData()); // Tom
class Person {
data: string = 'Person';
getData = () => {
return this.data;
}
}
const lee = new Person();
const tom = {
data: 'Tom',
getData: lee.getData
}
console.log(lee.getData()); // Person
console.log(tom.getData()); // Person
is
class Person<T> {
value?: T;
hasValue(): this is { value: T } {
return !!this.value;
}
isClass<T extends Function>(target: T): this is T {
return this instanceof target;
}
}
class Person extends Person<any> {
}
const person: Person<any> = new Person();
const lee: Person = new Person();
console.log(person.isClass(Person)); // true
console.log(lee.isClass(Person)); // true
console.log(lee.isClass(Person)); // true
console.log(person.hasValue()); // false
person.value = 'Person';
console.log(person.hasValue()); // true
抽象类和成员
抽象类中可以没有抽象方法,但抽象方法一定在抽象类中
抽象类只能被继承,不能被实例化
派生类必须实现抽象类的抽象成员
abstract class Person<T> {
constructor(public data: T) {
this.data = data;
}
getData() {
this.sayHello();
return this.data;
}
abstract sayHello(): void;
}
class Person<T> extends Person<T> {
sayHello() {
console.log('Hello');
}
}
const lee = new Person<object>({name: 'Person'});
console.log(lee.getData()); // Hello ---> { name: 'Person' }
ES模块
// 模块脚本
class Person {
name: string = 'Person';
age: number = 25;
}
export class Tom {
name: string = 'Tom';
age: number = 10;
}
export default Person;
// 入口脚本
// 1、引入方式 export default
// import Person from "./modules/Person";
// 2、引入方式 export
// import {Tom} from "./modules/Person";
// 3、引入方式 export 别名
// import {Tom as NewTom} from "./modules/Person";
// 4、引入方式 综合
import Person, {Tom, Tom as NewTom} from "./modules/Person";
// 4、引入方式 *
import * as Data from "./modules/Person";
console.log(Person, Tom, NewTom, Data.Tom, Data.default); // [class Person] [class Tom] [class Tom] [class Tom] [class Person]
CommonJS模块
exports.属性$
npm i --save-dev @types/node
// 模块脚本
class Lee {
name: string = 'Lee';
age: number = 25;
}
class Tom {
name: string = 'Tom';
age: number = 10;
}
exports.data = {
Lee,
Tom
}
// 入口脚本
let person = require('./modules/Person');
console.log(person); // { data: { Lee: [class Lee], Tom: [class Tom] } }
module.exports
// 模块脚本
class Lee {
name: string = 'Lee';
age: number = 25;
}
class Tom {
name: string = 'Tom';
age: number = 10;
}
module.exports = {
Lee,
Tom
}
// 入口脚本
let person = require('./modules/Person');
console.log(person); // { Lee: [class Lee], Tom: [class Tom] }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)