1、准备
// 安装
npm i typescript -g
// 版本
tsc -v
// 默认调试,-w表监听所有ts文件,编译为js文件,再通过node运行js文件
tsc -w index.ts
node index.js
// 生成tsconfig.json
tsc --init
nodejs 环境执行ts
npm i ts-node -g
npm i @types/node -D
ts-node index.ts
2、基础类型
基础类型:Boolean、Number、String、null、undefined、Symbol、BigInt
Ⅰ. 字符串类型
let str:string = 'Avido';
let str2:string = `hey ${str}`; // 模板字符串
Ⅱ. 数字类型
NaN 和 Infinity都属于number类型。
let num_nan:number = NaN;
let num_infinity:number = Infinity;
let num:number = 1008611;
let decimal:number = 6; // 十进制
let hex:number = 0xf00d; // 十六进制
let binary:number = 0b1010; // 二进制
let octal:number = 0o744; // 八进制
Ⅲ. 布尔类型
使用构造函数Boolean创造的对象不是布尔值。
let createBoolean:boolean = new Boolean(); // 报错,new Boolean()返回对象
// a. 直接使用布尔值
let b1:boolean = true;
// b. 通过函数返回布尔值
let b2:boolean = Boolean(1);
Ⅳ. 空值类型
void: 没有返回值,常用于函数声明。
void可以定义undefined 和null类型。
function myFn():void {
console.log('hey, ok!');
}
let v1:void = null; // 严格模式下会报错
let v2:void = undefined;
void 和undefined 、null的区别:undefined、null是所有类型的子类型。
// 如下面报错:
let test:void = undefined;
let test2:string = "1";
let test3:null = null;
let test4:undefined = undefined;
test2 = test; // void类型无法分给其他类型
test2 = test3; // 严格模式下报错
test2 = test4; // 严格模式下报错
注:关闭严格模式
tsc --init 生成tsconfig.json,将"strict" 的值设置为false
// 非严格模式下穿插赋值
let n:null = null;
let u:undefined = undefined;
// n = u;
// u = n;s
3、任意类型
any unknown
丢失类型检查。声明变量没有指定变量类型时默认为any。
Ⅰ. 类型,从上往下包含。如Object包括Boolean、Number、String。
Top Type 顶级类型 any unknown
Object
Boolean Number String
boolean number string
true 100 'abc'
never
let a: any = [];
a = 10010;
a = 'abcd';
a = Symbol(1);
Ⅱ. any与unknown的区别
a. unknown只能赋值给自身或者any
b. unknown无法读取任何属性、无法调用方法
c. unknown 比 any更加安全
// unknown类型只能作为父类型不能作为子类型
let a1:any = 1;
let un1:unknown = 5;
let au_num:number = 6;
a1 = un1;
un1 = a1;
au_num = a1;
// au_num = un1; // 无法赋值给number类型
let un2:unknown = {
name: 'ABC',
fn: () => {
console.log(111)
}
}
let a2:any = {
name: 'DEF',
fn: () => {
console.log(0o0);
}
}
// unknown无法读取属性和调用方法
// console.log(un2.name);
// console.log(un2.fn());
console.log(a2.name);
console.log(a2.fn());
console.log(a2.age);
4、Object object {}
Ⅰ. Object
所有原始类型和对象类型最终都指向Object。
Object接口定义了Object.prototype原型对象上的属性
let OB1:Object = 123;
let OB2:Object = [];
let OB3:Object = {};
let OB4:Object = () => 2333;
Ⅱ. object
常用于泛型约束,代表非原始类型的一个类型。
只能支持引用类型。
// let ob1:object = 123; // number
// let ob2:object = '123'; // string
// let ob3:object = false; // boolean
let ob4:object = []; // array
let ob5:object = {}; // object
let ob6:object = () => 0; // fn
Ⅲ. {}
字面量模式,相当于new Object
let eo1: {} = 123;
let eo2: {} = '123';
let eo3: {} = [];
let eo4: {} = {name:'I'};
// {} 无法进行赋值操作
// eo4.age = 11;
// eo4.name = '1123';
5、接口和对象类型( interface )
定义对象的方式用关键字 interface
定义一种约束,声明的变量要符合对应的数据结构。
Ⅰ. 重名的interface声明,会重合
interface Axx{
name: string,
age: number
}
interface Axx{
birthday: string
}
// 此时hey必须存在定义的三个属性,否则会报错
let hey: Axx = {
name: 'hey',
age: 24,
birthday: '1999-12-20'
}
Ⅱ. 任意key
只对必填字段做强校验,使用索引签名
interface Bxx{
name: string,
age: number,
[propName:string]: any
}
// 该对象必须存在name和age,其他可任意声明,不做校验
let hey2: Bxx = {
name: 'hey2',
age: 25,
sign: 'tag',
plus: 3.0
}
Ⅲ. ? readonly
可选变量 只读
readonly 一般用于不可修改的函数,或者id值只读
interface Cxx{
name: string,
age?: number, // age可选
readonly id: number,
readonly fn: () => boolean
}
let hey3: Cxx = {
name: 'hey3',
id: 111222,
fn: () => { return false }
}
hey3.name = 'heyy3';
// 为只读属性,不可重新赋值
// hey3.id = 222333;
// hey3.fn = () => { return true }
Ⅳ. 接口继承
声明的接口继承其他接口,在定义对象时,其他接口声明的属性也需要存在。
interface Dxx extends FXX,GXX{
name: string,
id: number
}
interface FXX{
zzz: boolean
}
interface GXX{
YYY: object
}
let hey4: Dxx = {
name: 'hey4',
id: 222333,
zzz: true,
YYY: []
}
Ⅴ. 定义函数类型
interface InFn{
// 参数为name,string类型;返回一个数字数组
(name: string): number[]
}
const fn: InFn = function(name: string) {
return [1,2,3]
}
6、数组类型
Ⅰ. 定义数组普通类型
// a.number[] boolean[] string[]
// b. 泛型 Array<boolean/number/string>
let arr1:number[] = [1,2,3];
let arr2:boolean[] = [true,false];
let arr3:string[] = ['1','0'];
let arr4:Array<number> = [3,6,9];
// arr1.unshift('1') // 数字类型数组
arr1.unshift(4);
console.log(arr1)
Ⅱ. 定义对象数组
interface X{
name: string,
age?: number
}
let arr5:X[] = [
{ name: 'i',age: 3 },
{ name: 'e' }
]
Ⅲ. 定义多维数组
let arr6:number[][] = [[1],[2]];
let arr7:Array<Array<number>> = [[1],[2]];
Ⅳ. 包含多种数据类型的数组
let arr8: any[] = [1,'str',false];
let arr9: [number, string, boolean, {}] = [1,'str',false, {}];
Ⅴ. 函数参数
参数作为一个数组在函数中调用。
类数组不属于数组,没有数组方法,ts内置对象IArguments定义类数组
function aFn(...args: number[]):void {
console.log(args,'args');
console.log(arguments,'arguments');
// let a:any[] = arguments; // 报错,伪数组不存在数组方法
let a:IArguments = arguments;
}
aFn(1,2);
// arguments 作为IArguments类型声明的原理
interface IA {
callee: Function,
length: number,
[index:number]: any
}
let fn_arguments: IA = {callee: () => {}, length: 888, 333:()=> {}}
7、函数扩展
Ⅰ. 普通函数/箭头函数定义参数类型和返回值
function add(a:number,b:number):number {
return a+b;
}
console.log(add(1,2))
const add2 = (a:number,b:number):number => {
return a+b;
}
console.log(add2(1,1))
Ⅱ. 函数设置参数默认值、设置可选参数
参数有默认值时,不可为可选参数
function add3(a:number = 10,b:number = 3):number {
return a+b;
}
console.log(add3());
function add4(a?:number,b?:number):number {
return (a ? a : 1) + (b ? b:1);
}
console.log(add4(4));
// 定义剩余参数
const fn_left = (arr: number[], ...items:any[]):any[] => {
console.log(arr,items);
return items;
}
let aa_left:number[] = [2,2,2];
fn_left(aa_left,'666',1008,false)
Ⅲ. 配合interface定义参数为对象类型的函数
interface User{
name: string,
age: number
}
function getUserInfo(user:User):User {
return user
}
console.log(getUserInfo({name: 'user', age: 999}));
interface IN_ADD{
(num1: number, num2: number) : number
}
const in_add:IN_ADD = (num1: number,num2: number): number =>{
return num1 + num2
}
console.log(in_add(5,5),'in_add')
Ⅳ. 函数this类型
interface Aee {
ae_arr: number[],
add: (num:number) => void
}
let aee: Aee = {
ae_arr: [1,1,3,5],
add (num:number) {
this.ae_arr.push(num); //? this无法获取ae_arr,实际在项目中是可以获取的
}
}
aee.add(8);
console.log(aee,'aee')
// ts可以定义this类型,且必须是第一个参数定义this的类型
interface Aee2 {
ae_arr: number[],
add: (this: Aee2, num: number) => void;
}
let aee2: Aee2 = {
ae_arr: [2,3,3],
add(this: Aee2,num: number) {
this.ae_arr.push(num)
}
}
aee2.add(6);
console.log(aee2,'aee2')
Ⅴ. 函数重载
通过函数是否有传参数、参数类型等,定义函数不同功能。
例如在一个函数实现增删改查:
let num_arr:number[] = [1,2,3];
function findNum(id:number):number[] // 传指定值,做查询
function findNum():number[] // 无参数,查询全部
function findNum(arr:number[]):number[] // 传数组,做新增
function findNum(ids?:number | number[]):number[] {
if(typeof ids === 'number') {
return num_arr.filter(v => v === ids)
}
else if(Array.isArray(ids)) {
num_arr.push(...ids)
return num_arr
}
else {
return num_arr
}
}
console.log(findNum());
console.log(findNum(3));
console.log(findNum([7,8,9]))
8、联合类型 | 交叉类型 | 类型断言
Ⅰ. 联合类型
变量支持多种数据类型
let phone: string | number = '010-223344';
let phone2: string | number = 1008611;
let fn_getBool = function(type: number | boolean):boolean {
return !!type; // 强转
}
console.log(fn_getBool(1));
console.log(fn_getBool(false));
Ⅱ. 交叉类型
多种类型的集合。定义的对象包含多种属性
interface Person {
name: string,
age: number
}
interface Man {
sex: number
}
const getInfo = (man: Person & Man) : void => {
console.log(man)
}
getInfo({
name: 'Bepo',
age: 2333,
sex: 1
})
Ⅲ. 类型断言
值 as 类型 || <类型>值
类型断言只能欺骗ts编译器,无法避免运行时的错误
const getLength = (val: number | string) : void => {
// console.log(val.length); // 报错,number无法获取length
console.log((val as string).length);
// console.log((val as number).toFixed(2))
}
getLength(3.1415926);
getLength('3.1415926')
interface A{
get: string
}
interface B{
set: string
}
const getA = (type:A|B):void => {
console.log((<A>type).get)
}
getA({set: 'aaa'});
getA({get: 'bbb'});
Ⅳ, 临时断言
any临时断言: 在any类型上访问任何属性都是允许的
// 在window上挂属性或者方法
// any临时断言: 在any类型上访问任何属性都是允许的
// window.abc = 123; // 报错。window上不存在abc属性
(window as any).abc = 123;
Ⅴ. as const
const name1 = 'name1';
// name1 = '111' ; // 无法修改
let name2 = 'name2' as const;
// name2 = '222'; // 无法修改
const arr1_const = [10,20];
let arr2_const = [10,20] as const;
arr1_const.unshift(30);
// arr2_const.unshift(30); // 已经断言字面量为[10,20],无法修改
9、内置对象
Ⅰ.ECMA: Number Date RegExp Error XMLHttpRequest
let num_ecma:Number = new Number(1);
let date_ecma:Date = new Date();
let reg_ecma:RegExp = new RegExp(/\w/);
let err_ecma:Error = new Error('错误');
let xml_ecma:XMLHttpRequest = new XMLHttpRequest();
Ⅱ. DOM: querySelect MouseEvent
HTML(元素名称)Element HTMLElement as Element
let div1= document.querySelector('div');
let div2 = document.querySelector('header');
let div3 = document.querySelector('footer') as Element;
let div4:NodeList = document.querySelectorAll('div');
let div5:NodeListOf<HTMLDivElement | HTMLElement> = document.querySelectorAll('div footer');
Ⅲ. BOM: promise localStorage location cookie
let b_localStorage: Storage = localStorage;
let b_location: Location = location;
let b_promise: Promise<string> = new Promise((r) => r('str'));
b_promise.then(res => {
console.log(res.length) // 已声明为resolve为string类型,故可调用string方法
})
let cookie: string = document.cookie;
代码雨
//index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Avido</title>
<style>
* {
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="./index.js"></script>
</body>
</html>
// index.ts
let canvas= document.getElementById("canvas") as HTMLCanvasElement;
let ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
canvas.width = screen.availWidth;
canvas.height = screen.availHeight;
let rainStr: string[] = "ZYXDASGDUHLE293Y0102".split("");
let rainArr = Array(Math.ceil(canvas.width / 10)).fill(0);
// 创建数组,值为0,length为屏幕宽度/10
console.log(rainArr);
const rain = () => {
ctx.fillStyle = "rgba(0,0,0,0.05)"; // 背景色
ctx.fillRect(0, 0, canvas.width, canvas.height); //背景色铺满: x,y,width,height
ctx.fillStyle = "#0f0";
rainArr.forEach((item, index) => {
ctx?.fillText(
rainStr[Math.floor(Math.random() * rainStr.length)],
index * 10,
item + 10
); // 取数组随机数,在index*10,item+19的xy轴展示
rainArr[index] = item > canvas.height || item > 8000*Math.random() ? 0 : item + 10;
// console.log(rainArr[index]);
// item值超过屏幕高度或者取随机值置为0,即文字的展示高度(y轴)
});
};
setInterval(rain, 60)
// 运行
tsc -w
打开index.html