TypeScript 入门

课程地址

ts 开发环境搭建

npm i -g typescript

查看安装位置:

$ npm root -g
C:\Users\Daniel\AppData\Roaming\npm\node_modules

创建 hello.ts

console.log("hello, ts");

编译 ts 文件,得到 js 文件:

$ tsc foo.ts

类型声明

后置的类型声明

let a: number;a = 10;
a = 33;
// a = "hello";let b: string = "hello";
let c = true;   // Automatic type inferencefunction sum(a: number, b: number): number {return a + b;
}console.log(sum(1, 2));

类型

在这里插入图片描述

// 字面量类型
let a: 10;  // const a = 10;// 联合类型
let b: "male" | "female";
let c: boolean | string;
c = true;
c = "hello"// any 与 unknown
let d: any;
d = "hello";let e: unknown;
e = "hello";let s: string = d;
// s = e;   Type 'unknown' is not assignable to type 'string'
s = e as string;
s = <string>e;function f(): void {return;
}function f2(): never {  // 永远不会返回结果,终止进程throw new Error("error");
}

unknown 本质上是一个类型安全的 any

// 对象类型
let b: {name: string,age?: number,   // ? -> optional
};b = {name: "sunwukong"
};let c: {name: string,[propName: string]: any,
};// 函数类型
let d: (a: number, b: number) => number;d = function(a, b) {return a + b;
}// 数组类型
let e: string[];
e = ["a", "b", "c"];let g: Array<number>;
g = [1, 2, 3];// 元组
let h: [string, string];// enum
enum Gender {Male = 0,Female = 1,
}let p: {name: string, gender: Gender}p = {name: "sunwukong",gender: Gender.Male,
}// & 类型
let j: {name: string} & {age: number};// 类型别名
type t1 = 1 | 2 | 3 | 4 | 5;
let m: t1;

tsc 编译选项

自动编译文件

tsc foo.ts -w	# 文件改变时自动编译
tsc		# 根据 tsconfig.json 编译

tsconfig.json

{/*** 表示任意目录* 表示任意文件*/"include": ["./*"],"exclude": ["foo.ts"],// "files": ["./app.ts", "./index.ts"],"compilerOptions": {"target": "ES6",     // 指定 es 版本// "module": "ES6",// "lib": ["DOM"]"outDir": "./dist",// "outFile": "./dist/app.js",  // 将编译结果合并到 app.js"allowJs": false,"checkJs": false,   // 对 js 也做类型检查"removeComments": false,"noEmit": true,     // 不生成编译后的文件,只检查"noEmitOnError": true,   // 当有错误时不生成编译后的文件"strict": true,     // 打开下面的所有严格检查/*"alwaysStrict": true,   // -> use strict"noImplicitAny": true,"noImplicitThis": true,"strictNullChecks": true,*/},
}

使用 webpack 打包 ts 代码

npm init -y		# 初始化项目
npm i -D webpack webpack-cli typescript ts-loader

配置 webpack.config.js

const path = require("path");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: "ts-loader",exclude: /node_modules/}]},mode: 'development',
}

配置 tsconfig.json

{"compilerOptions": {"module": "es6","target": "es6","strict": true,}
}

package.json 中增加 script 配置

  "scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack"},

最后 npm run build 即可

安装 3 个插件:

npm i -D html-webpack-plugin	# 生成 html 测试文件
npm i -D webpack-dev-server		# 编辑后自动重启服务
npm i -D clean-webpack-plugin	# 清除 dist 目录再构建
npm i -D @babel/core @babel/preset-env babel-loader core-js

package.json 中编写 webpack-server 的启动脚本:

  "scripts": {"start": "webpack serve --open"},

webpack.config.ts 中引入插件(使用 template.html 作为生成模板):

const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: [{loader: "babel-loader",options: {presets: [["@babel/preset-env",{targets: {"chrome": "88"},"corejs": "3","useBuiltIns": "usage"  // 按需加载}]]}},"ts-loader"],exclude: /node_modules/}]},mode: 'development',plugins: [new HTMLWebpackPlugin({// title: "mytitle"template: "./src/template.html"}),new CleanWebpackPlugin(),],resolve: {  // 设置引用模块extensions: [".ts", ".js"]}
}

OOP

class

class Person {name: string = "sunwukong";static age: number = 18;readonly gender: string = "M";sayHello() {console.log("hello");}
}let p = new Person();console.log(p);
console.log(Person.age);
p.sayHello();

构造函数和 this

class Dog {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}bark() {console.log(`${this.name}: wangwang`);}
}let d = new Dog("wangcai", 4);console.log(d);
d.bark();

继承

class Animal {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHello() {console.log("sayHello()");}
}class Dog extends Animal{run(){console.log(`${this.name} is running`);}sayHello(): void {  // 子类重写父类方法console.log("wangwangwang");}
}class Cat extends Animal{sayHello(): void {  // 子类重写父类方法console.log("miaomiaomiao");}
}const d1 = new Dog("wangcai", 5);
console.log(d1);
d1.sayHello();const c1 = new Cat("mimi", 3);
c1.sayHello();

super

super 表示父类

class Animal {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log("sayHello()");}
}class Dog extends Animal {age: number;constructor(name: string, age: number) {super(name);this.age = age;}sayHello(): void {console.log("wangwangwang");}
}const d1 = new Dog("wangcai", 3);
console.log(d1);    // Dog { name: 'wangcai', age: 3 }
d1.sayHello();      // wangwangwang

抽象类

使用 abstract 修饰的类,不能用于实例化对象,只能被继承

抽象类中可以添加抽象方法,抽象方法必须被子类重写

abstract class Animal {name: string;constructor(name: string) {this.name = name;}abstract sayHello(): void;  // 必须被子类重写
}class Dog extends Animal {sayHello(): void {console.log("wangwangwang");}
}const d1 = new Dog("wangcai");
console.log(d1);    // Dog { name: 'wangcai', age: 3 }
d1.sayHello();      // wangwangwang

接口

用来定义一个类的结构(一个类应该包含哪些属性和方法,做类型限制)

接口中的所有属性都不能带有实际的值,接口只定义对象的结构(全是抽象方法),而不考虑实际值

interface Person{name: string;age: number;
}// 接口可以分离定义
interface Person {gender: string;sayHello(): void;
}class Male implements Person {name: string;age: number;gender: string;constructor(name: string, age: number, gender: string) {this.name = name;this.age = age;this.gender = gender;}sayHello(): void {console.log("hello");}
}

属性访问控制

class Person {private _name: string;private _age: number;constructor(name: string, age: number) {this._name = name;this._age = age;}get name() {        // per.namereturn this._name;}set name(name: string) {this._name = name;}get age() {return this._age;}set age(age: number) {if (age >= 0) {this._age = age;}}
}const p1 = new Person("sunwukong", 18);
console.log(p1);p1.name = "zhubajie";
console.log(p1);
console.log(p1.age);class C {// 直接将属性和访问控制定义在构造函数中constructor(public name: string, public age: number) {}
}

泛型

function fn<T> (a: T): T {return a;
}fn(10);
fn<string>("hello");function bar<T, K>(a: T, b: K): T {console.log(b);return a;
}bar<number, string>(10, "hello");interface Inter {length: number;
}
// 使用接口约束泛型的类型参数
function foo<T extends Inter>(a: T): number {return a.length;
}foo("123");     // string 有 length
foo({length: 10});// 类的泛型
class C<T> {name: T;constructor(name: T) {this.name = name;}
}const c = new C<string>("sunwukong");

贪吃蛇练习

// package.json
{"name": "snake","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack serve --open"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.23.9","@babel/preset-env": "^7.23.9","babel-loader": "^9.1.3","clean-webpack-plugin": "^4.0.0","core-js": "^3.35.1","css-loader": "^6.10.0","html-webpack-plugin": "^5.6.0","less": "^4.2.0","less-loader": "^12.2.0","style-loader": "^3.3.4","ts-loader": "^9.5.1","typescript": "^5.3.3","webpack": "^5.89.0","webpack-cli": "^5.1.4","webpack-dev-server": "^4.15.1"}
}
// tsconfig.json
{"compilerOptions": {"module": "es6","target": "es6","strict": true,"noEmitOnError": true}
}
// webpack.config.ts
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: [{loader: "babel-loader",options: {presets: [["@babel/preset-env",{targets: {"chrome": "88"},"corejs": "3","useBuiltIns": "usage"  // 按需加载}]]}},"ts-loader"],exclude: /node_modules/},{test: /\.less$/,use: ["style-loader","css-loader","less-loader"]}]},mode: 'development',plugins: [new HTMLWebpackPlugin({// title: "mytitle"template: "./src/template.html"}),new CleanWebpackPlugin(),],resolve: {  // 设置引用模块extensions: [".ts", ".js"]}
}
// index.ts
import "./style/index.less"
import Food from "./modules/food"
import ScorePanel from "./modules/score_panel"
import GameControl from "./modules/game_control";const f = new Food();
f.change();const gc = new GameControl();
// snake.ts
class Snake {head: HTMLElement;bodies: HTMLCollection;element: HTMLElement;constructor() {this.head = document.querySelector("#snake > div")!;this.bodies = document.getElementById("snake")!.getElementsByTagName("div");this.element = document.getElementById("snake")!;}get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}set X(x: number) {if (this.X === x) return;if (x < 0 || x > 290) {throw new Error("snake_dead");}if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === x) {if (x > this.X) {x = this.X - 10;} else {x = this.X + 10;}}this.moveBody();this.head.style.left = x + "px";this.checkHeadBody();}set Y(y: number) {if (this.Y === y) return;if (y < 0 || y > 290) {throw new Error("snake_dead");}if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === y) {if (y > this.Y) {y = this.Y - 10;} else {y = this.Y + 10;}}this.moveBody();this.head.style.top = y + "px";this.checkHeadBody();}addBody() {this.element.insertAdjacentHTML("beforeend", "<div></div>");}moveBody() {for (let i = this.bodies.length - 1; i > 0; i--) {let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;(this.bodies[i] as HTMLElement).style.left = X + "px";(this.bodies[i] as HTMLElement).style.top = Y + "px";}}checkHeadBody() {for (let i = 1; i < this.bodies.length; i++) {let bd = this.bodies[i] as HTMLElement;if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {throw new Error("snake_dead");}}}
}
export default Snake;
// score_panel.ts
class ScorePanel {score = 0;level = 1;scoreEle: HTMLElement;levelEle: HTMLElement;maxLevel: number;upScore: number;constructor(maxLevel: number = 10, upScore: number = 10) {this.scoreEle = document.getElementById("score")!;this.levelEle = document.getElementById("level")!;this.maxLevel = maxLevel;this.upScore = upScore;}addScore() {this.scoreEle.innerHTML = ++this.score + "";if (this.score % this.upScore === 0) {this.levelUp();}}levelUp() {if (this.level < this.maxLevel) {this.levelEle.innerHTML = ++this.level + "";}}
}
export default ScorePanel;
// game_control.ts
import Snake from "./snake";
import Food from "./food";
import ScorePanel from "./score_panel";class GameControl {snake: Snake;food: Food;scorePanel: ScorePanel;direction: string = "";isLive = true;constructor() {this.snake = new Snake();this.food = new Food();this.scorePanel = new ScorePanel();this.init();}keydownHandler = (event: KeyboardEvent) => {this.direction = event.key;}init() {document.addEventListener("keydown", this.keydownHandler);this.run();}run() {let X = this.snake.X;let Y = this.snake.Y;switch(this.direction) {case "ArrowUp":Y -= 10;break;case "ArrowDown":Y += 10;break;case "ArrowLeft":X -= 10;break;case "ArrowRight":X += 10;break;}this.checkEat(X, Y);try {this.snake.X = X;this.snake.Y = Y;} catch (e) {alert((e as Error).message);this.isLive = false;}this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);}checkEat(x: number, y: number) {if (x === this.food.X && y === this.food.Y) {console.log("ate food");this.food.change();this.scorePanel.addScore();this.snake.addBody();}}}export default GameControl;
// food.ts
class Food {element: HTMLElement;constructor() {// `!` 表示判定该语句的结果不可能为空this.element = document.getElementById("food")!;}get X() {return this.element.offsetLeft;}get Y() {return this.element.offsetTop;}change() {let left = Math.round(Math.random() * 29)* 10;let top = Math.round(Math.random() * 29)* 10;this.element.style.left = top + "px";this.element.style.top = left + "px";}
}
export default Food;
// index.less
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font: bold 20px Courier;
}#main {width: 360px;height: 420px;background-color: #b7d4a8;margin: 100px auto;border: 10px solid black;border-radius: 10px;display: flex;flex-flow: column;align-items: center;justify-content: space-around;#stage {width: 304px;height: 304px;border: 2px solid black;position: relative;#snake {&>div {width: 10px;height: 10px;background-color: black;border: 1px solid #b7d4a8;position: absolute;}}#food {width: 10px;height: 10px;position: absolute;left: 40px;top: 100px;display: flex;flex-flow: row wrap;justify-content: space-between;align-content: space-between;&>div {width: 4px;height: 4px;background-color: black;}}}#score-panel {width: 300px;display: flex;justify-content: space-between;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/681314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode二叉树的垂序遍历

题目描述 给你二叉树的根结点 root &#xff0c;请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言&#xff0c;其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 (0, 0) 。 二叉树的 垂序遍历 从最左边的列开始直到…

ubuntu22.04@laptop OpenCV Get Started: 007_color_spaces

ubuntu22.04laptop OpenCV Get Started: 007_color_spaces 1. 源由2. 颜色空间2.1 RGB颜色空间2.2 LAB颜色空间2.3 YCrCb颜色空间2.4 HSV颜色空间 3 代码工程结构3.1 C应用Demo3.2 Python应用Demo 4. 重点分析4.1 interactive_color_detect4.2 interactive_color_segment4.3 da…

使用Docker,拉取Nginx镜像,创建并运行Nginx容器

查看DockerHub&#xff0c;拉取Nginx镜像&#xff0c;创建并运行Nginx容器。 在DockerHub中搜索Ningx镜像&#xff0c;查看镜像名称 拉取Nginx镜像 [rootservice ~]# systemctl start docker [rootservice ~]# mkdir -p /etc/docker [rootservice ~]# tee /etc/docker/daemo…

Imgui(1) | 基于imgui-SFML改进自由落体小球

Imgui(1) | 基于imgui-SFML改进自由落体小球 0. 简介 使用 SFML 做2D图形渲染的同时&#xff0c;还想添加一个按钮之类的 GUI Widget, 需要用 Dear Imgui。由于 Imgui 对于2D图形渲染并没有提供类似 SFML 的 API, 结合它们两个使用是一个比较好的方法, 找到了 imgui-SFML 这个…

C++,stl,map/multimap详解

目录 1.map的构造和赋值 2.map的大小和交换 3.map的插入和删除 4.map的查找和统计 5.map的排序 1.map的构造和赋值 #include<bits/stdc.h> using namespace std;void print(map<int,int> &mp) {for(map<int,int>::iterator it mp.begin(); it ! m…

数据库管理-第150期 Oracle Vector DB AI-02(20240212)

数据库管理150期 2024-02-12 数据库管理-第150期 Oracle Vector DB & AI-02&#xff08;20240212&#xff09;1 LLM2 LLM面临的挑战3 RAG4 向量数据库LLM总结 数据库管理-第150期 Oracle Vector DB & AI-02&#xff08;20240212&#xff09; 作者&#xff1a;胖头鱼的鱼…

2.8:Maefile、计算单词个数、判断文件类型、单词逆置

1.有main.c&#xff0c;test.c&#xff0c;test1.c&#xff0c;创建Makefile 程序代码&#xff1a; Makefile: 1 CCgcc2 EXEhello3 OBJS$(patsubst %.c,%.o,$(wildcard *.c))4 CFLAGS-c -o5 all:$(EXE)6 7 #hello依赖test.o main.o8 $(EXE):$(OBJS)9 $(CC) $^ -o $10 …

除了ajax还有什么方法获取数据而不用刷新数据

除了AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;&#xff0c;还有以下几种方法可以在不刷新页面的情况下获取数据&#xff1a; Fetch API&#xff1a;Fetch API 是一个现代的网络 API&#xff0c;提供了一个 JavaScript Promise 对象来处理网络请求。Fetch …

腾讯云4核8G服务器多少钱?646元一年零3个月

腾讯云服务器4核8G配置优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;腾讯云百科txybk.com分…

算法学习——LeetCode力扣二叉树篇8

算法学习——LeetCode力扣二叉树篇8 669. 修剪二叉搜索树 669. 修剪二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high…

[leetcode]买卖股票的最佳时机 (动态规划)

121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从…

恒创科技:香港 BGP 服务器网络连通性如何测试?

随着互联网的快速发展&#xff0c;网络连通性测试变得越来越重要。网络连通性测试的目的是确定网络设备之间的连接是否正常&#xff0c;以及数据包是否能够在网络中顺利传输。本文将介绍一种简单易行的香港 BGP 服务器网络连通性的测试方法&#xff0c;利用tracer测试工具。这里…

springboot184基于springboot的校园网上店铺的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

幻兽帕鲁 Linux 服务器迁移完成之后,进入游戏会出现闪退?怎么解决?

主要的原因是迁移的存档文件&#xff0c;新服务器可能没有操作存档文件的权限&#xff0c;不能成功更新存档&#xff0c;从而导致闪退。 建议&#xff1a;在 Linux 服务器内&#xff0c;依次运行如下命令后&#xff0c;再次尝试连接游戏&#xff1a; 第一步&#xff1a; s…

分布式认证JWT

JWT解释 JWT是一种加密后的数据载体&#xff0c;可在各应用间进行数据传输。 JWT的组成 包含3部分。header&#xff08;头&#xff09;、payload&#xff08;有效载荷&#xff09;、signature&#xff08;签名&#xff09;。格式是header.payload.signature Header组成 JWT…

JAVA-数组乱序

实现步骤 假设有一组数组numbers从数组中最后一个元素开始遍历设置一个随机数作为循环中遍历到的元素之前的所有元素的下标&#xff0c;即可从该元素之前的所有元素中随机取出一个每次将随机取出的元素与遍历到的元素交换&#xff0c;即可完成乱序 实例如下&#xff1a; im…

day39 Bootstrap——容器简括

前言 前言Bootstrap5 容器容器内边距容器的边框和颜色响应式容器 前言 Bootstrap&#xff0c;来自 Twitter&#xff0c;是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的&#xff0c;它简洁灵活&#xff0c;使得 Web 开发更加快捷。 Bootstrap5 容器 B…

2022年美赛A题个人思路

一、读题 自行车运动员获胜的机会不同&#xff0c;但取决于赛事的类型、路线和自行车运动员的能力。 能量曲线&#xff1a;表明自行车运动员可以产生给定能量的时间长短对于特定的时间长度&#xff0c;能量曲线提供了自行车运动员在给定时间内保持的最大能量。 &#xff08;1&a…

wayland(xdg_wm_base) + egl + opengles 纹理贴图进阶实例(四)

文章目录 前言一、使用gstreamer 获取 pattern 图片二、代码实例1. pattern 图片作为纹理数据源的代码实例1.1 基于opengles2.0 接口的 egl_wayland_texture2_1.c1.2 基于opengles3.0 接口的 egl_wayland_texture3_1.c2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c3…

大模型LoRA知识

什么是 LoRA&#xff1f; LoRA&#xff08;low-rank adaptation of large language models&#xff09;是一种针对大型语言模型进行低秩适应的技术。大型语言模型通常具有数十亿个参数&#xff0c;这使得它们在计算和存储方面非常昂贵。低秩适应的目标是通过将语言模型的参数矩…