稀土掘金-typescript史上最强学习入门文章(2w字)typescript史上最强学习入门文章(2w字)
文章目录
1-搭建typescript学习环境编译选项
基础数据类型JS的八种内置类型注意点nulll 和 undefinednumber和bigint
其他类型Array函数Tuple(元组)voidneveranyunknow
1-搭建typescript学习环境
安装最新版typescript: 安装环境:需要先安装Node,之后:npm install -g typescript 使用tsc -V查看安装的ts版本。
tsc : 无法将“tsc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。 这个错误是 没有安装tsc 写好XXX.ts文件,使用 tsc 文件名将ts文件编译为js文件。因为浏览器不支持ts文件,无法直接在浏览器运行ts文件,需要编译为js文件
创建一个 tsconfig.json 文件
变量声明和复制同时进行,TS可以自动对变量进行类型检查let c= false 此时c的类型就是布尔
// 给参数 返回值指定类型
function sum(a: number, b: number): number {
return a + b;
}
// 调用sum参数 不能少些参数 不能多写参数
编译选项
文件变化,自动编译tsc 文件名 -w 是对当前文件进行过监视,自动编译 自动编译所有文件 项目根目录下新建tsconfig.json 之后tsc -w命令即可监视项目中所有的ts文件 但是有时候我们不需要编译项目中所有的ts文件,需要对tsconfig.json进行配置 include 指定哪些ts文件需要编译 **表示任意目录 *表示任意文件, 如 ./src/**/* src下任意目录任意文件都可以进行编译 exclude 表示不编译, 有默认值[ "node_modules", "bower_components", "jspm_packages" ] extends 定义被继承的配置文件 如extends: "./configs/base"表示当前配置文件中会自动包含config目录下base.json中所有配置信息 files:["a.ts", "b.ts"] 列表中所有文件都会被TS编译器所编译
“alwaysStrict”: true设置编译后的文件是否使用严格模式, 默认是false. 为true则使用严格模式,就像js文件头添加"use strict"。 如下编译后输出的文件默认添加"use strict"; 如果指定输出合并一个文件如app.js则在app.js添加"use strict"; 没指定合并一个文件,在编译后的每个文件添加"use strict"; // true不允许隐式any “noImplicitAny”: true // true: 不允许不明确类型的this “noImplicitThis”: true 解决:指定this为Window或者this: any等方式
function fn(this: Window) {
alert(this)
}
// true: 严格检查空值 “strictNullChecks”: true
let box1 = document.getElementById(".box1")
// 方式一 if判断
if (box1 != null) {
box1.addEventListener("click", function () {
alert("hello world!")
});
}
// 方式二
box1?.addEventListener("click", function () {
alert("hello world!")
});
// 所有严格检查的总开关,true则 “alwaysStrict” “noImplicitAny” “noImplicitThis” "strictNullChecks"都为true, // 一般放在上面 “strict”: true 汇总
{
"include": ["./src/**/*"],
"exclude": ["./src/hello/**/*"],
"compilerOptions": {
// target 编译成那个版本。默认是ES3。常见ES6, ESNext表示最新的ES版本
//target选项 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'esnext'
"target": "es6",
// 使用模块化的规范 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node16', 'nodenext'.
// 使用了导入模块话 module需要用system
"module": "system",
// lib 用来指定项目中要使用的库, lib一般不需要修改
// '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017',
// 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'es2023', 'esnext', 'dom',
// 'dom.iterable', 'webworker', 'webworker.importscripts', 'webworker.iterable',
// 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator',
// 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect',
// 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include',
// 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl',
// 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable',
// 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object',
// 'es2019.string', 'es2019.symbol', 'es2019.intl', 'es2020.bigint', 'es2020.date',
// 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown',
// 'es2020.intl', 'es2020.number', 'es2021.promise', 'es2021.string', 'es2021.weakref',
// 'es2021.intl', 'es2022.array', 'es2022.error', 'es2022.intl', 'es2022.object',
// 'es2022.sharedmemory', 'es2022.string', 'es2022.regexp', 'es2023.array',
// 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl',
// 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref',
// 'decorators', 'decorators.legacy'.
// "lib": []
// 指定 编译完的文件所在目录 "./dist"
"outDir": "./dist",
// 将编译后代码合并为1个文件,设置outFile后,所有全局作用域中的代码合并到同一个文件中,如./dist/app.js
// 使用了导入模块话 module需要用system
"outFile": "./dist/app.js",
// 是否对 js 文件进行编译,默认是false, 如src先有hello.js文件则不会编译,输出dist没有hello.js文件
"allowJs": true,
// 是否检查js代码是否符合语法规范,默认是false. true代表:如JS文件检查是否符合ts规范 , h=3, 将h="ss"就不符合ts规范
"checkJs": false,
// 是否移除注释
"removeComments": true,
// true: 不生成编译后的文件,即不会有dist文件夹。默认值为false
"noEmit": false,
// true: 当有错误时不生成编译后的文件件,即不会有dist文件夹, 没有错误则生成dist。.默认值为false
"noEmitOnError": true,
// 设置编译后的文件是否使用严格模式, 默认是false. 为true则使用严格模式,就像js文件头添加"use strict"
"alwaysStrict": true,
// true不允许隐式any
"noImplicitAny": true,
// true: 不允许不明确类型的this
"noImplicitThis": true,
// true: 严格检查空值
"strictNullChecks": true,
// 所有严格检查的总开关,true则 "alwaysStrict" "noImplicitAny" "noImplicitThis" "strictNullChecks"都为true,
// 一般放在上面
"strict": true
}
}
基础数据类型
JS的八种内置类型
let str: string = "hello world!"
let num: number = 23
let bool: boolean = false
let u: undefined = undefined
let n: null = null
let obj: object = { x: 1 }
// 目标低于 ES2020 时,BigInt 字面量不可用。ts(2737)
//需要将ts编译成js, bigint是es2020才识别,所以需要编译到某个版本,解决方法:编写配置文件
let big: bigint = 100n;
let sym: symbol = Symbol("me")
注意点
nulll 和 undefined
默认情况下null 和 undefined 是所有类型的子类型,可以把 null 和 undefined赋值给其他类型
// null和undefined赋值给string
let str:string = "666";
str = null
str= undefined
// null和undefined赋值给number
let num:number = 666;
num = null
num= undefined
// null和undefined赋值给object
let obj:object ={};
obj = null
obj= undefined
// null和undefined赋值给Symbol
let sym: symbol = Symbol("me");
sym = null
sym= undefined
// null和undefined赋值给boolean
let isDone: boolean = false;
isDone = null
isDone= undefined
// null和undefined赋值给bigint
let big: bigint = 100n;
big = null
big= undefined
如果你在tsconfig.json指定了"strictNullChecks":true ,null 和 undefined 只能赋值给 void 和它们各自的类型。 建议"strictNullChecks":true
number和bigint
两者都表示数字,但两者不兼容
let big: bigint = 100n
let num: number = 0;
// 不能将类型“number”分配给类型“bigint”。
big = num
// 不能将类型“bigint”分配给类型“number”。
num = big
会抛出一个类型不兼容的 ts(2322) 错误。
其他类型
Array
对数组类型的定义有两种方式:
let arr: string[] = ['12', '123']
let arr2: Array
定义联合类型数组
// 定义一个数组,可以存储number和string的数据
let arr3: (number | string)[]
arr3 = [1, 'b']
定义指定对象成员的数组:
// interface是接口,后面会讲到
interface Arrobj{
name:string,
age:number
}
let arr3:Arrobj[]=[{name:'jimmy',age:22}]
函数
函数声明
function sum(x: number, y: number): number {
return x + y;
}
函数表达式
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
用接口定义函数类型
interface SearchFunc{
(source: string, subString: string): boolean;
}
可选参数
function bindName(firstName: string, secondName?: string) {
if (secondName) {
return firstName + " " + secondName;
}
return firstName;
}
let tomcat = bindName("Tom", "Cat")
let tom = bindName("Tom")
注意点:可选参数后面不允许再出现必需参数
参数默认值
function bindName(firstName: string, secondName: string="Cat") {
return firstName + " " + secondName;
}
let tomcat = bindName("Tom", "Cat")
let tom = bindName("Tom")
剩余参数
function push(array: any[], ...items: any[]) {
items.forEach(function(item) {
array.push(item);
});
}
let a = [];
push(a, 1, 2, 3);
由于 JavaScript 是一个动态语言,我们通常会使用不同类型的参数来调用同一个函数,该函数会根据不同的参数而返回不同的类型的调用结果
function add(x, y) {
return x + y;
}
add(1, 2); // 3
add("1", "2"); //"12"
使用函数重载
type Types = number | string
function add(a:number,b:number):number;
function add(a: string, b: string): string;
function add(a: string, b: number): string;
function add(a: number, b: string): string;
function add(a:Types, b:Types) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
const result = add('Semlinker', ' Kakuqo');
result.split(' ');
Tuple(元组)
元祖用于保存定长定数据类型的数据
let x: [string, number]
// 类型必须匹配且个数必须为2
x = ['hello', 10]; // OK
x = ['hello', 10,10]; // Error
x = [10, 'hello']; // Error
注意,元组类型只能表示一个已知元素数量和类型的数组,长度已指定,越界访问会提示错误。如果一个数组中可能有多种类型,数量和类型都不确定,那就直接any[]
void
never
any
unknow
字面量
// 字面量场景:限制赋值的值或者类型
let b: boolean | number
// b只能是 boolean或者number类型,其他类型报错
b = false;
b = 12;
// 限制值 只能male或female
let c: "male" | "female";
c = "male";
c = "female";
any
// any是任意类型,相当于对该变量关闭TS类型检查
let d: any
unknown 是未知类型
let f: unknown;
f = "ss"
f = false;
any和unknown的区别
// 区别 将any类型赋值给别的变量不会报错,而unknown会报错
let s: string
s = d // d类型是any s是string 进行赋值不报错
// s = f;// f类型是unknown s是string 进行赋值报错
// 如何让 unknown赋值不报错: 类型断言 写法有两种 as 类型或<类型>
s = f as string
s =
void 和never
// 返回值为空
function f(): void{ }
// never表示没有返回值,连空都没有
function nf(): never {
throw new Error("报错")
}
约束函数与对象
let b: object; //指定b是object类型
let b1: { name: string, a?: number } // 指定b必须有name属性且值为string, a是可选属性
let b2: { name: string, [propName: string]: any } // 指定必须与name属性,其他属性名必须为stirng,属性值随意
// 约束函数
let d: (a: number, b: number) => number
// 函数d必须有两个参数且返回值类型为number
d = function (n1, n2) {
return n1 + n2
}
约束数组
// 约束e只能是存储string类型的数组
let e: string[]
e = ["1", "2"]
let g: number[]
let h: Array
元组:固定长度的数组 枚举
// 只有两个string元素的元组
let h: [string, string]
let o= { name:"h", gender: 1}
// 枚举
enum Gerder{
Male,
Female,
}
console.log(o.gender == Gerder.Female)
类型别名
type myType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
let k: myType
k = 4
推荐阅读
发表评论