JavaScript进阶7之TypeScript

JavaScript进阶7

TypeScript

安装Typescript编译器

npm install -g typescript

初始化

tsc -init

关于ts配置项,tsconfig.json
文档解读

typescript 复制代码
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Projects */
    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */

    /* Language and Environment */
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
    // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
    // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
    // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
    // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
    // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
    // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
......

    /* Emit */
    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
.......
}

声明空间

类型声明空间

typescript 复制代码
class Foo {}
interface Bar {}
type Bas = {}

let foo:Foo
let bar:Bar
let bas:Bas

变量声明空间

typescript 复制代码
// 变量声明空间
class Test {}
const a = Test
const b = 2

一些小知识点

导入导出

typescript 复制代码
//a.ts
export const foo=123
typescript 复制代码
//b.ts
import { foo } from "./a";
const bar = foo

import { xxx } from 'xxx'

引入的是文件的类型,导出的时候也是按照文件模块/类型引用

global.d.ts

全局模块,是全局直接用

typescript 复制代码
declare module svg  //定义全局类型

再 tsconfig includes注入

基础语法

类型注解

typescript 复制代码
// type annotation 类型注解
const num :number =123

function sum(a:number,b:number):string{
    return a+b.toString()
}

变量类型

基本类型
typescript 复制代码
// 基本类型
let num:number
let str:string
let bool:boolean  //Boolean是构造函数,但是boolean只是类型

num=123
str='abc'
bool=false

// 数组
let numberList:number[]
let strList:Array<string>
let numStr:Array<number|string>  // (string|number)[]

numberList=[1,2,3,4]
strList =['1','2','3','4']
numStr = [1,'2',3,'4']
接口
typescript 复制代码
// 外联接口
interface Person{
    name:string,
    age?:number  //等同于:age:number|undefined,表示age可有可无
}

let person:Person
person={
    name:'张三',
    age:undefined
}
typescript 复制代码
// 内联接口
let person:{
    name:string,
    age:number
}|{sex:string}={
    name:"张三",
    age:14
}
特殊类型

any undefined void null

typescript 复制代码
// 特殊类型  any undefined void null
let num:any
let str:string

num=undefined
// strictNullChecks:false  关闭严格检查
// 则 str=undefined 不会报错

function sendMsg(msg:string):void{
    console.log(msg);
}

type noop = () =>void  //函数声明
泛型
typescript 复制代码
function reverse<T>(items:T[]):T[]{
    let list=[]
    for (let i = items.length-1; i >= 0; i--) {
        list.push(items[i])
    }
    return list
}

const a=[1,2,3]

let reverseA=reverse(a)

reverseA=[3]
交叉类型
typescript 复制代码
// 交叉类型
function a<T extends object,U extends object>(name:T,age:U):T&U{
    return {
        ...name,
        ...age
    }
}

let resultA=a(['张三','李四'],{age:15})
元祖类型
typescript 复制代码
// 元组类型
let a:[string,number]

a=['张三',15]
type
typescript 复制代码
// type
type cType=string|number
let c:cType='155'
type和interface的区别
  1. type是类型的结合,interface是数据结构的描述
  2. 二者在继承上基本一致,但是写法上是不同的
    interface继承:
typescript 复制代码
interface Shape{
    x:number,
    y:number
}
interface Recentangle extends Shape{
    x:number,
    height:number
}

const a:Recentangle={
    x:0,
    y:10,
    height:10
}
typescript 复制代码
type Shape={
    x:number,
    y:number
}

type Circle = Shape&{
    r:number
}
const c:Circle={
    x:10,
    y:10,
    r:5
}

@types/react

@types/react -> devDependency 16.8

react -> dependencies 16.8

import React from 'react'

@types是约定俗成的

引用的是类型声明包

.d.ts是所有类型的集合,全称是:declaration type 都是通过 @types/react去管理的

typescript 复制代码
interface Process{
    exit(code?:number):void
}
declare var process:Process
process.exit()

或者:

typescript 复制代码
declare var process:{
    exit(code?:number):void
}
process.exit()

以上两种写法,一般都用第一种写法,比较规范,考虑到代码扩展性等

enum枚举

typescript 复制代码
// 枚举
enum Shape{
    circle,
    rect,
    a,
    b,
    c
}

const shape=Shape.circle


typescript 复制代码
enum Weekday {
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}
namespace Weekday {
    export function isBusinessDay(day: Weekday) {
        switch (day) {
            case Weekday.Saturday:
            case Weekday.Sunday:
                return false;
            default:
                return true;
        }
    }
}

const mon = Weekday.Monday
const sun = Weekday.Sunday
console.log(Weekday.isBusinessDay(mon)); // true
console.log(Weekday.isBusinessDay(sun));

函数

函数声明

typescript 复制代码
interface Foo{
    b:string
}
function foo(a:string,c?:number):Foo{
    const b="1"
    return {
        b
    }
}
foo('123',123)
foo('345')

函数重载

针对不同场景下参数的兼容,参数不同,则场景不同,考虑到的情况也不一样

类型约束

typescript 复制代码
// 类型约束 typeof instanceof in
function a(x:number|string){
    if(typeof x==='number'){

    }
}

interface A{
    x:number
}
interface B{
    y:string
}
function aa(c:A|B){
    if('x' in c){
        
    }
}

Infer

获取函数参数类型

typescript 复制代码
type ParamType<T> = T extends (arg: infer P) => any ? P : T;

使用:

typescript 复制代码
type ParamType<T> = T extends (arg: infer P) => any ? P : T;
interface User {
    name: string;
    age: number;
}
  
type Func = (user: User) => void;

type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string

const param:Param={
    name:'张三',
    age:18
}

const aa:AA="111"

console.log(param);
console.log(aa);
  1. ParamType<T> 的定义
typescript 复制代码
type ParamType<T> = T extends (arg: infer P) => any ? P : T;

这里定义了一个名为 ParamType 的类型别名,它是一个条件类型。条件类型的形式为 T extends U ? X : Y,表示如果类型 T 可以赋值给类型 U,则结果类型为 X,否则为 Y。

  • (arg: infer P) => any:这是一个函数类型,其中 infer P 表示推断函数参数的类型。如果 T 是一个函数类型,这里会尝试从该函数中推断出参数的类型。

  • P:如果 T 是一个符合上述函数类型的类型(即,如果 T 是一个函数),则 ParamType<T> 将被解析为该函数的参数类型。

  • T:如果 T 不符合上述函数类型(即,T 不是一个函数类型),ParamType<T> 将直接被解析为 T 本身。

  1. FuncParam 的定义
typescript 复制代码
interface User {
    name: string;
    age: number;
}

type Func = (user: User) => void;

type Param = ParamType<Func>; // Param = User
  • User 是一个接口,定义了具有两个属性 nameage 的对象类型。

  • Func 是一个函数类型,接受一个 User 类型的参数并返回 void

  • Param 使用 ParamType 来推断 Func 函数的参数类型。由于 Func 是一个接受 User 类型参数的函数,因此 Param 被解析为 User

  1. AA 的定义
typescript 复制代码
type AA = ParamType<string>; // string
  • AA 通过使用 ParamType 来处理 string 类型。由于 string 并不是一个函数类型,因此 ParamType<string> 直接解析为 string

    总结:

  • ParamType<T> 能够从函数类型中提取参数类型,或直接返回非函数类型的类型。

获取函数返回值

typescript 复制代码
type ReturnType<T> = T extends (...args: any[]) => infer P ? P : any;

这里同样是一个条件类型的定义,形式为 T extends U ? X : Y

  • (...args: any[]) => infer P:这是一个函数类型,其中 ...args: any[] 表示函数接受任意数量的任意类型参数,infer P 表示推断函数返回值的类型。

  • P:如果 T 是一个符合上述函数类型的类型(即,如果 T 是一个函数类型),则 ReturnType<T> 将被解析为该函数的返回值类型。

  • any:如果 T 不符合上述函数类型(即,T 不是一个函数类型),ReturnType<T> 将直接被解析为 any 类型。

    使用:

typescript 复制代码
// 获取函数返回值
type ReturnTyped<T>=T extends (...args:any[])=>infer P?P:any;

type Func=(numList:number[])=>number[]

type returnFun=ReturnTyped<Func>
type AAFun=ReturnTyped<string>

const ret:returnFun=[1,2,3,4]
const aa:AAFun=1255
const bb:AAFun="12"
const cc:AAFun=[1,'2',4]

console.log("ret",ret);
console.log("aa",aa);
console.log("bb",bb);
console.log("cc",cc);

Run-time Check运行时类型检查

运行时候类型检测 Zod

Zod 既能运行在服务端,也能运行在客户端

typescript 复制代码
// Run-time check 运行时类型检查
import { z } from "zod";

// creating a schema for strings
const mySchema = z.string();

// parsing
var tuna=mySchema.parse("tuna"); // => "tuna"
console.log(tuna);
// mySchema.parse(12); // => throws ZodError

// "safe" parsing (doesn't throw error if validation fails)
var tunaSafe=mySchema.safeParse("tuna"); // => { success: true; data: "tuna" }
console.log(tunaSafe);
var safe12=mySchema.safeParse(12); // => { success: false; error: ZodError }
console.log(safe12);

运行执行:

tsc --lib es2015 .\04-运行时类型检查.ts

node .\04-运行时类型检查.js

对于对象处理:

typescript 复制代码
import {z} from 'zod'

const User=z.object({
    name:z.string()
})

var obj=User.parse({name:"张三"})
console.log("obj",obj);

type UserMore=z.infer<typeof User>

const user:UserMore={
    name:"李四"
}

console.log("user",user);

tsc .\04-运行时类型检查.ts //报错没关系,已经编译成js了

node .\04-运行时类型检查.js

装饰器

tsc --target ES5 --experimentalDecorators

tsconfig.ts

typescript 复制代码
{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true
  }
}

方法装饰

typescript 复制代码
function foo(){
    console.log("foo 开始");
    return function(target:Object,propertyKey:string,descriptor:PropertyDescriptor){
        console.log("foo 执行");
    }
}

function bar(){
    console.log("bar 开始");
    return function(target:Object,propertyKey:string,descriptor:PropertyDescriptor){
        console.log("bar 执行");
    }
}

class CType{
    @foo()
    @bar()
    cFunc(){}
}

const c=new CType()
c.cFunc()
相关推荐
波音彬要多做21 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
Swift社区29 分钟前
Excel 列名称转换问题 Swift 解答
开发语言·excel·swift
一道微光33 分钟前
Mac的M2芯片运行lightgbm报错,其他python包可用,x86_x64架构运行
开发语言·python·macos
矛取矛求37 分钟前
QT的前景与互联网岗位发展
开发语言·qt
Leventure_轩先生37 分钟前
[WASAPI]从Qt MultipleMedia来看WASAPI
开发语言·qt
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
是娜个二叉树!1 小时前
图像处理基础 | 格式转换.rgb转.jpg 灰度图 python
开发语言·python
Schwertlilien1 小时前
图像处理-Ch5-图像复原与重建
c语言·开发语言·机器学习
liuyunshengsir1 小时前
Squid代理服务器的安装使用
开发语言·php
暴富的Tdy1 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js