TS的基本知识

1、类型声明

let 变量: 类型;

let 变量: 类型 =;

function fn(参数: 类型, 参数: 类型): 类型{
    ...
}

let fn1:function fn(参数: 类型, 参数: 类型)=>返回值类型
  • ts拥有自动判题机制

2、类型

类型例子描述
number1, -33, 2.5任意数字
string‘hi’, “hi”, hi任意字符串
booleantrue、false布尔值true或false
字面量其本身限制变量的值就是该字面量的值
any*任意类型
unknown*类型安全的any
void空值(undefined)没有值(或undefined)
never没有值不能是任何值
object{name:‘孙悟空’}任意的JS对象
array[1,2,3]任意JS数组
tuple[4,5]元素,TS新增类型,固定长度数组
enumenum{A, B}枚举,TS中新增类型

1)ts类型 :用 | 来连接多个类型 --联合类型

let b : "male" | "female"
b = "male"
b = "female"
b = "str" //报错

let c : boolean | string
c = true
c = "str"
c = 1 //报错

2)any:可以赋值给其他任意变量

let d
let e: any
d = "a"
d = 1

e = "a"
e = 1

3):unknown:表示未知类型的值,不能赋值给其他任意变量

let c:string
c = "str"
let s : unknown
s= "1"
s = 1
s= true
c = s //报错
  • 类型断言:可以告诉解析器变量的实际类型

    let c:string
    let s : unknown
    c = s as string //不报错
    c = <string>s //不报错
    

4)void:表示空,如果是函数则表示没有返回值

function sum(a: number, b: number) { 
//function sum(a: number, b: number): void  
}

function sum(a: number, b: number) { 
//function sum(a: number, b: number): number
    return a + b
}
  • 可以返回nullundefined

5)never:表示永远不会返回结果

function fn(): never {
    throw new Error("报错了!")
}

function fn(): never { //报错:返回“从不”的函数不能具有可访问的终结点
}

6)object:表示一个 js 对象

let b: { name: string, age: number }
b = {} //报错
b = { name: "hhh" } //报错 -> 如果想不报错,就要在b的属性age后面加上? let b: { name: string, age?: number }
b = { name: "hhh", age: 18 } //不报错

let c: { name: string, [propName: string]: any }
c = { name: "ggg", a: 1, b: true } //不报错
  • {}用来指定对象可以包含哪些属性
  • 语法:{属性名:属性值,属性名:属性值,…}
  • 在属性名后面加上?表示属性是可选的
  • [propName: string]: any :表示任意类型的属性

7)数组

let a: string[]
a = ["a", "b"]
let b: number[]
b = [1, 3]
let c: Array<number>
c = [2, 4]
  • 类型[ ]
  • Array<类型>

8)元组:固定长度的数组

let h :[string,number]
h = ["hello",1]

9):enum:枚举

enum Color {
    Red = 1,
    Green = 2,
    Blue = 3,
}
let a: { name: string, likeColor: Color }
a = { name: "hh", likeColor: Color.Blue }

10):&表示同时

let j: { name: string } & { age: number }
j = { name: "hh" } //报错
j = { name: "hh", age: 18 } //不报错

11)类型的别名

type myTypes = 1 | 2 | 3
let k : myTypes

k = 2 //不报错
k = 4 //报错:不能将类型“4”分配给类型“myTypes

3、ts编译选项

编译配置文件:tsconfig.json

{
  "compilerOptions": { // 编译选项
    "target": "esnext", // 设置ts代码编译的目标版本
    // ES3(默认)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
    "module": "esnext", //设置编译后代码使用的模块化系统
    // CommonJS、UMD、AMD、System、ES2020、ESNext、None
    "outDir": "dist", // 编译后文件的所在目录
    "strict": true, // 用所有的严格检查,默认值为true
    "jsx": "preserve",
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": true,
    "sourceMap": true, // 是否生成sourceMap,默认值:false
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [ // 指定代码运行时所包含的库(宿主环境)
      // ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext、DOM、WebWorker、ScriptHost ......
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  // 希望被编译的文件 默认["**/*"]
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  // 希望不被编译的文件 默认["node_modules", "bower_components", "jspm_packages"]
  "exclude": [
    "node_modules"
  ]
}
  • 严格检查:

    • strict
      • 启用所有的严格检查,默认值为true,设置后相当于开启了所有的严格检查
    • alwaysStrict
      • 总是以严格模式对代码进行编译
    • noImplicitAny
      • 禁止隐式的any类型
    • noImplicitThis
      • 禁止类型不明确的this
    • strictBindCallApply
      • 严格检查bind、call和apply的参数列表
    • strictFunctionTypes
      • 严格检查函数的类型
    • strictNullChecks
      • 严格的空值检查
    • strictPropertyInitialization
      • 严格检查属性是否初始化
  • 额外检查

    • noFallthroughCasesInSwitch
      • 检查switch语句包含正确的break
    • noImplicitReturns
      • 检查函数没有隐式的返回值
    • noUnusedLocals
      • 检查未使用的局部变量
    • noUnusedParameters
      • 检查未使用的参数
  • 高级

    • allowUnreachableCode
      • 检查不可达代码
      • 可选值:
        • true,忽略不可达代码
        • false,不可达代码将引起错误
    • noEmitOnError
      • 有错误的情况下不进行编译
      • 默认值:false

4、webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
   optimization:{
       minimize: false // 关闭代码压缩,可选
   },

   entry: "./src/index.ts",

   devtool: "inline-source-map",

   devServer: {
       contentBase: './dist'
   },

   output: {
       path: path.resolve(__dirname, "dist"),
       filename: "bundle.js",
       environment: {
           arrowFunction: false // 关闭webpack的箭头函数,可选
       }
   },

   resolve: {
       extensions: [".ts", ".js"]
   },

   module: {
       rules: [
           {
               test: /\.ts$/,
               use: {
                   loader: "ts-loader"     
               },
               exclude: /node_modules/
           }
       ]
   },
   plugins: [
       new CleanWebpackPlugin(),
       new HtmlWebpackPlugin({
           title:'TS测试'
       }),
   ]
}

引入Babel对代码进行转换,以使其可以兼容到更多的浏览器

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
   optimization:{
       minimize: false // 关闭代码压缩,可选
   },

   entry: "./src/index.ts",

   devtool: "inline-source-map",

   devServer: {
       contentBase: './dist'
   },

   output: {
       path: path.resolve(__dirname, "dist"),
       filename: "bundle.js",
       environment: {
           arrowFunction: false // 关闭webpack的箭头函数,可选
       }
   },

   resolve: {
       extensions: [".ts", ".js"]
   },

   module: {
    	rules: [
            {
                test: /\.ts$/,
                use: [
                    {
                        loader: "babel-loader",
                        options:{
                            presets: [
                                [
                                    "@babel/preset-env",
                                    {
                                        "targets":{
                                            "chrome": "58",
                                            "ie": "11"
                                        },
                                        "corejs":"3",
                                        "useBuiltIns": "usage"
                                    }
                                ]
                            ]
                        }
                    },
                    {
                        loader: "ts-loader",

                    }
                ],
                exclude: /node_modules/
            }
        ]
   },

   plugins: [
       new CleanWebpackPlugin(),
       new HtmlWebpackPlugin({
           title:'TS测试'
       }),
   ]
}

如此一来,使用ts编译后的文件将会再次被babel处理;

使得代码可以在大部分浏览器中直接使用;

同时可以在配置选项的targets中指定要兼容的浏览器版本;

5、类

class 类名{
    属性名= 属性值;
    属性名= 属性值;
    属性名= 属性值;
    ...
    
    // 方法
    方法名(){
        ...
    }
}

// 1. 使用方式
// 1) new
const xx =  new 类名
xx.属性名
// 2)直接使用(这个需要在属性名前面加上 static,变成静态属性)
类目.属性名 

// 2. 只读属性 readonly -> 添加到属性名前面(在 static 后面),只允许读取,不允许修改

6、构造函数

class Dog {
    name: string
    age: number

    constructor(name:string , age:number){
        this.name = name
        this.age = age
    }
}

const dog1 = new Dog("小黑", 20)
const dog2 = new Dog("小白", 20)

7、extends:继承

class 父类{
    属性名: 类型;
    属性名: 类型;
    ...
    
    方法名(){
        
    }
}

class 子类 extends 父类{
    // 如果方法名和父类的相同,就相当于重写了父类方法,但父类不受影响
    方法名(){
        
    }
}

8、super

class 父类{
    父类属性名: 类型;
    父类属性名: 类型;
    ...
    
    constructor(父类属性名:类型 , 父类属性名:类型){
        this.父类属性名 = 父类属性名
        this.父类属性名 = 父类属性名
    }
}

class 子类 extends 父类{
    子类属性名: 类型;
    ...
    
    // 因为方法名一致,所以会重写父类方法,所以要先调用父类方法
    constructor(父类属性名:类型 , 子类属性名:number){
        super(父类属性名:类型 , 父类属性名:类型)
        this.子类属性名 = 子类属性名
    }
    
}

9、abstract 抽象:出生就是为了当爸爸的

abstract class 父类{
    父类属性名: 类型;
    父类属性名: 类型;
    ...
    
    constructor(父类属性名:类型 , 父类属性名:类型){
        this.父类属性名 = 父类属性名
        this.父类属性名 = 父类属性名
    }
	
	// 子类必须重写父类的方法
	abstract 方法名():[返回参数];
}

class 子类 extends 父类{
	// 重写父类方法
	方法名():[返回参数]{
        ...
    } 
}

10、interface:接口(implements)

interface myInter {
    name: string
    fn(): void
}

class myClass implements myInter{
    name: string
    constructor(name:string){
        this.name = name
    }
    fn(): void {
        console.log("实现了接口方法");
        
    }
}

11、封装

public:

class Person{
    public name: string; // 写或什么都不写都是public
    public age: number;

    constructor(name: string, age: number){
        this.name = name; // 可以在类中修改
        this.age = age;
    }

    sayHello(){
        console.log(`大家好,我是${this.name}`);
    }
}

class Employee extends Person{
    constructor(name: string, age: number){
        super(name, age);
        this.name = name; //子类中可以修改
    }
}

const p = new Person('孙悟空', 18);
p.name = '猪八戒';// 可以通过对象修改

protected:

class Person{
    protected name: string;
    protected age: number;

    constructor(name: string, age: number){
        this.name = name; // 可以修改
        this.age = age;
    }

    sayHello(){
        console.log(`大家好,我是${this.name}`);
    }
}

class Employee extends Person{

    constructor(name: string, age: number){
        super(name, age);
        this.name = name; //子类中可以修改
    }
}

const p = new Person('孙悟空', 18);
p.name = '猪八戒';// 不能修改

private:

class Person{
    private name: string;
    private age: number;

    constructor(name: string, age: number){
        this.name = name; // 可以修改
        this.age = age;
    }

    sayHello(){
        console.log(`大家好,我是${this.name}`);
    }
}

class Employee extends Person{

    constructor(name: string, age: number){
        super(name, age);
        this.name = name; //子类中不能修改
    }
}

const p = new Person('孙悟空', 18);
p.name = '猪八戒';// 不能修改

属性存取器

对于一些不希望被任意修改的属性,可以将其设置为private

直接将其设置为private将导致无法再通过对象修改其中的属性

我们可以在类中定义一组读取、设置属性的方法,这种对属性读取或设置的属性被称为属性的存取器

读取属性的方法叫做setter方法,设置属性的方法叫做getter方法

示例:

class Person{
    private _name: string;

    constructor(name: string){
        this._name = name;
    }

    get name(){
        return this._name;
    }

    set name(name: string){
        this._name = name;
    }

}

const p1 = new Person('孙悟空');
// 实际通过调用getter方法读取name属性
console.log(p1.name);
// 实际通过调用setter方法修改name属性 
p1.name = '猪八戒'; 

简写属性

class Dog{
    constructor(name:string,age:number){}
}

const dog = new Dog("小黑",2)

12、泛型

// 泛型函数
function test<T>(arg: T): T{
    return arg;
}

// 泛型类
class MyClass<T>{
  prop: T;

  constructor(prop: T){
      this.prop = prop;
  }
}

// 泛型继承
interface MyInter{
  length: number;
}

function test<T extends MyInter>(arg: T): number{
  return arg.length;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值