Typescript:基础语法学习(尚硅谷 李立超)
官方文档:https://www.tslang.cn/docs/handbook/typescript-in-5-minutes.html
搭建开发环境
npm i -g typescript
安装完成界面:
查看是否安装完成,输入以下命令:tsc
执行命令:node
文件名``
编译代码
tsc 01_HelloTs.ts
基础语法
变量声明
// 生命一个变量a,同时指定他的类型为number
let a: number
// a的类型不能修改
a = 10
a = 50
// 字符串
let b: string
b = 'hello'
// 布尔值
// let c:boolean = false
// 如果变量的声明和赋值时同时进行的,TS可以自动对变量进行类型检测
let c = false
c = true
变量定义后,类型不能修改
字面量和联合类型
// 直接使用字面量进行类型声明, 类似于常量
let a: 10
a = 10
// 可以使用|来连接多个类型(联合类型)
let b: "male"| "female"
b = "male"
b = "female"
let c: boolean|string
c = true
c = "hello"
任意值 any
可以赋予变量任意类型的值
声明变量如果不指定类型,则TS解析器会自动判断变量的类型为any
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
断言
let e = "hello"
// 类型断言, 可以用来告诉解析器变量的实际类型
let s = e as string
s = <string>e
void 空值
// void用来表示空,以函数为例,就表示没有返回值的函数
function fn():void{
}
object 对象
// object表示一个js对象
let a: object;
a = {}
a = function () {
}
定义对象结构
// [propName:string]:any 表示任意类型的值
let c: {name:string, [propName:string]:any};
c = {name:'leo', age:18}
设置函数解构的类型声明
// 设置函数解构的类型声明
// 语法:(形参:类型,形参:类型……)=>返回值
let d: (a:number, b:number) => number
数组
// string[],表示字符串数组
let e:string[]
e = ['a', 'b', 'c']
// number[], 表示数值
let f: number[]
f = [1,2,3]
let g: Array<number>
g = [1,2,3]
枚举类型
// 枚举类型
enum Gender{
male = 0,
female = 1
}
let i: {name:string, gender:Gender}
i = {
name: '孙悟空',
gender: Gender.male
}
console.log(i.gender === Gender.male) // true
表示同时
// &表示同时
let j: {name: string} & {age:number}
j = {name: '孙悟空', age: 18}
console.log(j) //{ name: '孙悟空', age: 18 }
类型的别名
// 类型的别名
type myTye = 1|2|3|4|5
let k: myTye
k = 1
编译选项
生成tsconfig.json
全部编译
实时监听
tsc -w
webpack
初始化文件
安装依赖
npm i -D webpack webpack-cli typescript ts-loader
增加配置文件
- 添加
webpack.config.js
// 引入一个包
const path = require('path')
// webpack中的所有的配置信息都应该写在module.exports中
module.exports = {
// 指定入口文件
entry: "./src/index.ts",
// 指定打包文件所在目录
output:{
// 指定打包文件的目录
path: path.resolve(__dirname, 'dist'),
// 打包后文件的名称
filename: "bundle.js"
},
// 指定webpack打包时要使用的模块
module:{
// 指定要加载的规则
rules: [
{
// test指定的是规则生效的文件
test: /\.ts$/,
// 要使用的loader
use: 'ts-loader',
// 要排除的文件
exclude: /node-modules/
}
]
}
}
- 添加
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "es6",
"strict": true
}
}
- 在
package.json
中添加命令脚本
"build": "webpack"
编译命令
npm run build
自动生成html文件
npm i -D html-webpack-plugin
- 文件配置
// webpack.config.js
// 引入html文件
const HTMLWebpackPlugin = require('html-webpack-plugin');
// 配置webpack插件
plugins:[
new HTMLWebpackPlugin(
{
template: './src/index.html'
}
),
]
在项目中安装浏览器
npm i -D webpack-dev-server
- 文件配置
"start": "webpack server --open chrome.exe"
- 启动命令
npm start
安装bable
npm i -D @babel/core @babel/preset-env babel-loader core-js
类实例
class Dog{
// 构造函数
constructor(name: string, age: number){
// 在实例方法中,this就表示当前的实例
// 在构造函数中当前对象就是当前新建的那个对象
// 可以通过this想新建的对象中添加属性
this.name = name
this.age = age
}
bark(){
alert("qqq")
}
}
const dog = new Dog('小河', 4)
console.log(dog) //Dog { name: '小河', age: 4 }
继承
class Animal{
// 构造函数
constructor(name: string, age: number){
this.name = name
this.age = age
}
sayHello(){
console.log("动物在叫")
}
}
// extend 继承关键字
class Dog extends Animal{
run(){
console.log(`${this.name}再跑`)
}
}
class Cat extends Animal{
}
const dog = new Dog('小河', 4)
const cat = new Cat('咪咪', 3)
console.log(dog)
dog.sayHello()
dog.run()
console.log(cat)
cat.sayHello()
运行结果如下所示:
super
简单示例
class Animal{
name : string
constructor(name:string){
this.name = name
}
sayHello(){
console.log("动物在叫~~")
}
}
class Dog extends Animal{
sayHello(){
// 在类方法中,super表示当前类的父类
super.sayHello()
}
}
const dog = new Dog("旺财")
dog.sayHello() //动物在叫~~
子类中构造函数的使用
class Animal{
name : string
constructor(name:string){
this.name = name
}
sayHello(){
console.log("动物在叫~~")
}
}
class Dog extends Animal{
age: number
constructor(name:string,age: number){
// 如果在子类中写了构造函数,在类构造函数中必须添加super方法
super() // 调用父类的构造函数
this.age = age
}
sayHello(){
// 在类方法中,super表示当前类的父类
super.sayHello()
}
}
const dog = new Dog("旺财", 3)
dog.sayHello() //动物在叫~~
抽象类
关键字 abstract
/*
以abstract开头的类是对象类
抽象类和其他类区别不大,只是不能用来创建对象
抽象类就是专门用来被继承的类
抽象类中可以添加抽象方法
*/
abstract class Animal{
name : string
constructor(name:string){
this.name = name
}
// 定义一个抽象方法
/*
抽象方法使用abstract开头,没有方法体
抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
*/
abstract sayHello():void
}
class Dog extends Animal{
sayHello(){
console.log('汪汪汪')
}
}
class Cat extends Animal{
sayHello(){
console.log('喵喵喵')
}
}
接口 interface
接口定义
/*
接口用来定义一个类结构
同时接口也可以当成类型声明去使用
*/
// 定义一个接口,并声明属性
interface myInterface{
name: string
age: number
}
const obj: myInterface = {
name: 'sss',
age: 111
}
console.log(obj) //{ name: 'sss', age: 111 }
// 再次定义接口,并新增属性,此时接口中有三个属性
interface myInterface{
gender: string
}
const obj: myInterface = {
name: 'sss',
age: 111,
gender: '男'
}
console.log(obj) // { name: 'sss', age: 111, gender: '男' }
接口属性
/*
接口可以在定义类是去限制类的结构
接口中的所有的属性都不能有实际的值
接口只定义对象的结构,而不考虑实际的值
在接口中所有的方法都是抽象方法
*/
interface myInter{
name: string
sayHello():void
}
接口就是定义一个规范,是对类的限制
/*
定义类时,可以使用类去实现一个接口
实现接口就是让类满足接口的要求
*/
// 接口就是定义一个规范,是对类的限制
class MyClass implements myInter{
name: string
constructor(name:string){
this.name = name
}
sayHello(){
console.log('大家好~~~')
}
}
属性的封装
/*
ts可以在属性前添加属性的修饰符
public 修饰的属性可以在任意位置访问,修改, 默认值
private 私有属性,私有属性只能在类内部进行访问,修改
通过在类中添加方法使得私有属性可以被外部访问
*/
class Person{
private _name:string;
private _age: number
constructor(name:string, age:number){
this._name = name
this._age = age
}
// 定义方法,用来获取私有name属性
getName(){
return this._name
}
// 定义方法,用来设置私有name属性
setName(value:string){
this._name = value
}
}
const per = new Person('孙悟空', 18)
console.log(per.getName()) //孙悟空
per.setName('123')
console.log(per.getName()) //123
get与set方法
/*
ts可以在属性前添加属性的修饰符
public 修饰的属性可以在任意位置访问,修改, 默认值
private 私有属性,私有属性只能在类内部进行访问,修改
通过在类中添加方法使得私有属性可以被外部访问
*/
class Person{
private _name:string;
private _age: number
constructor(name:string, age:number){
this._name = name
this._age = age
}
// 在ts中设置getter方法的方式
get name(){
return this._name
}
// set方法
set name(value){
this._name = value
}
}
const per = new Person('孙悟空', 18)
console.log(per.name) // 孙悟空
// 调用get方法
per.name = '猪八戒'
console.log(per.name) //猪八戒
proted
/*
protected 受保护的属性,只能在当前类和当前类的子类中访问,修改
*/
class A{
protected num: number
constructor(num:number){
this.num = num
}
}
class B extends A{
test(){
console.log(this.num)
}
}
直接将函数定义在构造函数中
class C{
// 可以直接将属性定义在构造函数中
constructor(public name:string, public age:number){
}
}
const c = new C('xxx', 111)
console.log(c) // C { name: 'xxx', age: 111 }
等价于
class C{
constructor(name:string, age:number){
this.name = name
this.age = age
}
}
泛型
/*
在定义函数或是类时,如果遇到类型不明确就可以使用泛型
泛型指不确定的类型
*/
function fn<T>(a: T):T{
return a
}
// 可以直接調用具有范型的函数
let result = fn(10) // 不指定泛型,TS可以自动对类型进行判断
let result2 = fn<string>('hello') // 指定泛型
// 泛型可以同时指定多个
function fn2<T, K>(a: T,b: K):T{
console.log(b)
return a
}
fn2<number, string>(123, 'hello')
interface Inter{
legth: number
}
//
function fn3<T extends Inter>(a: T): number{
return a.length;
}
class MyClass<T>{
name: T;
constructor(name: T){
this.name = name
}
}
const mc = new MyClass<string>("will")
学以致用,知行合一