TypeScript语言

概述

  • 静态类型与动态类型
  • JavaScript自有类型系统的问题
  • Flow静态类型检查方案
  • TypeScript语言规范与基本应用

强类型与弱类型

  • 强类型与弱类型 从类型安全的角度区分
    • 强类型 :从语言层面限制函数的实参类型必须与形参类型相同
    • 弱类型语言:并不会去限制 有隐式类型转换

静态类型动态类型语言

是否允许类型转换,从类型检查的角度区分

javascript类型系统特征

可以说没有类型系统,任性 丢失类型系统的可靠性,

没有类型检查,因为没有编译阶段

弱类型的问题

  • 运行阶段才能发现类型异常
  • 类型不明确,函数功能会发生改变 类型转换 加减法变拼接
  • 对象索引器的用法

强类型的优势

  • 错误可以更早暴露
  • 代码更智能,编译更准确
  • 重构更牢靠
  • 减少类型判断

Flow 类型注解

  • 安装Flow
yarn add flow-bin --dev
  • 禁用vscode的Javascript验证
    • 设置->搜索JavaScript.validate
  • 初始化.flowconfig文件
yarn flow init
// 启动flow
yarn flow
// 停止flow
yarn flow stop

移除类型注解

  1. 通过flow官方的flow-remove-types模块

安装

yarn add flow-remove-types --dev

移除

// . 当前目录下的文件 输出到 dist 目录下
yarn flow-remove-types . -d dist
  1. 通过babel

安装

// @babel/core 核心模块
// @babel/cli 命令行工具
// babel/preset-flow 转换类型注解的插件
yarn add @babel/core @babel/cli @babel/preset-flow --dev

添加.balelrc配置文件

{
// 配制
"presets":["@babel/preset-flow"],
}

运行

yarn babel src -d dist

Flow开发工具插件

  • Flow Language Support 官方插件

flow插件支持的编辑器的情况

Flow 类型推断

类型注解

// 函数返回值
function add(a,b):number{ 
    return a+b
} 
// 没有返回值
function add(a,b):void{
    
}
// 变量
var num:number = 123 

Flow原始类型

flow支持那些类型

const a:string = 'foobar'
const b:number = Infinity // Nan // 100
const c:boolean = false // true
const d:null = null
const e:void = undefined
const f:symbol = Symbol()

数组类型

const arr1:Array<number> = [1,2,3,4]
const arr2:number[] = [1,2,3,4]
// 只能存放两位元素(元组)
// 一个函数如果要返回多个返回值时使用元组
const foo:[string,number] = ['foo',100]

对象类型

// 只能有两个成员
const obj1:{foo:string,bar:number}={foo:'string',bar:100}
// 成员名后加?表示可有可无
const obj2:{foo?:string,bar:number}={bar:100}
// 对象的键和值都是string类型的
const obj3:{[string]:string} = {}

Flow函数类型

// 对函数参数是回调函数的限制
function foo(callback:(string,number)=>void){}

Flow特殊类型

// 字面类型
const a:'foo' = 'foo'
// 只能存放这三种值之一
const type:'success'|'warning'|'danger' = "success"

const b:string|number

// type声明类型
type StringOrNumber = string|number
const b:StringOrNumber = 'string'

const gender:?number = undefined
// 相当与
const gender:number|null|void=undefined

Flow Mixed 与 Any

// mixed任何类型都可以 但使用时需要进行类型判断 强类型
function passMixed(value:mixed){
}
// 弱类型 不需要进行类型判断
function passAny(value:any){
    
}

Flow小结

Flow所有类型的描述文档

第三方类型手册

Flow运行环境api

const el:HTMlElement| null = document.getElementById('app')

api对应的声明文件的连接

javascript自身标准库中的成员

TypeScript

javascript的超集(superset)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7nzwP956-1647770112228)(E:\笔记\part2\TypeScript语言\TypeScript.png)]

TypeScript的基本使用

安装

// 初始化
yarn init --yes
// 安装
yarn add typescript --dev

node_modules/.bin/tsc文件用来编译ts文件

const hello = (a,b)=>a+b
console.log(hello(1,2))

编译

// yarn tsc 文件路径

yarn tsc 01-getting-started.ts

支持类型注解

typescript配置文件

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Projects */
    // "incremental": true,                              /* Enable incremental compilation */
    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // "tsBuildInfoFile": "./",                          /* Specify the folder for .tsbuildinfo incremental compilation files. */
    // "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 TC39 stage 2 draft 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. */

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
    // "moduleResolution": "node",                       /* 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. */
    // "resolveJsonModule": true,                        /* Enable importing .json files */
    // "noResolve": true,                                /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */

    /* JavaScript Support */
    // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */

    /* 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. */
    // "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. */
    // "outDir": "./",                                   /* Specify an output folder for all emitted files. */
    // "removeComments": true,                           /* Disable emitting comments. */
    // "noEmit": true,                                   /* Disable emitting files from a compilation. */
    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
    // "importsNotUsedAsValues": "remove",               /* Specify emit/checking behavior for imports that are only used for types */
    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
    // "newLine": "crlf",                                /* Set the newline character for emitting files. */
    // "stripInternal": true,                            /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like `__extends` in compiled output. */
    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
    // "preserveConstEnums": true,                       /* Disable erasing `const enum` declarations in generated code. */
    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
    // "preserveValueImports": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

    /* Interop Constraints */
    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied `any` type.. */
    // "strictNullChecks": true,  是否对null和undefined   /* When type checking, take into account `null` and `undefined`. */
    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
    // "strictBindCallApply": true,                      /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
    // "noImplicitThis": true,                           /* Enable error reporting when `this` is given the type `any`. */
    // "useUnknownInCatchVariables": true,               /* Type catch clause variables as 'unknown' instead of 'any'. */
    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
    // "noUnusedLocals": true,                           /* Enable error reporting when a local variables aren't read. */
    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read */
    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
    // "noUncheckedIndexedAccess": true,                 /* Include 'undefined' in index signature results */
    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type */
    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */

    /* Completeness */
    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

  • target 设置编译后的JavaScript标准
  • module 输出的语言采用什么样的方式进行模块化
  • outDir 编译结果输出到的文件夹
  • rootDir 源代码文件夹
  • sourceMap 开启源代码映射
  • strict 开启严格模式

直接运行yarn tsc 配置文件才会生效

yarn tsc

Ts原始数据类型

const a:string = 'foobar'
const b:number = 100  // 可以赋值为NaN Infinity
const c:boolean = true // false
// 非严格模式下 string number boolean 都可以为空(null)
const e:void = undefined // 非严格模式下可以是null
const f:null=null
const g:undefined= undefined
/**
* const h:symbel = Symbel()
* 会报错 将target修改为es2015
* 或者修改配置文件的lib  lib:['es2015','DOM']
* DOM 添加dom和bom的引用
*/
const h:symbel = Symbel() // 会报错 将target修改为es2015  修改配置文件的lib

中文错误消息

让ts显示中文的错误消息

yarn tsc --locale zh-CN

vscode 设置—>收缩typescript local—>选择zh-CN

不建议使用

TypeScript作用域问题

两个ts文件中的同一个变量不能定义在同一个作用域中

// 解决办法
(function(){
	const a=123
})()

// 或者
const a = 123
// 只是export的语法并不是导出了一个空对象
export {}

Object类型

ts中的object类型泛指所有非原始类型 即 object array function

const foo:object = function(){}  // [] // {}
// 对象
const obj :{foo:number,bar:string} = {foo:123,bar:'string'}
// 对象应该使用接口

TS数组类型

const arr1:Array<number> = [1,2,3]
const arr2:number[] = [1,2,3,4]

// 试用场景
function(...args:number[]){
    return args.reduce((prev,current)=>prev+current,0)
}

元组类型

明确元素数量及元素类型的数组

const tuple:[number,string] = [18,'string']

ts枚举类型

给一组数值起上一个更好理解的名字

只会出现固定的几个值

// enum 声明一个枚举值 
// 会被编译为一个双向的键值对对象  用键作为值再用值作为键
enum PostStatus{
    Draft=0,
    Unpublished=1,
    Published=2,
}
// 常量枚举
// 不会被编译 会将值直接赋值给用到的地方
const enum PostStatus1{
    Draft=0,
    Unpublished=1,
    Published=2,
}
const post = {
    title:"Hello TypeScript",
    constent:'TypeScript is a type superset of JavaScript.',
    // 使用
    status:PostStatus.Draft,
}

// 枚举类型可以不试用等号指定固定的值
// 会从0开始累加
// 如果指定了第一个值则从第一个值开始累加

注意:枚举类型会影响编译后的结果

函数的类型约束

function func1(a:number,b:number=10,...rest:number[]):string{
    return func1
}

const func2:(a:number,b:number)=>string = function(a:number,b:number):string{
    return  'asdf'
}

TS 任意类型

// Any Types  动态类型
function stringify(value:any){
    return JSON.stringify(value)
}

TS隐式类型推断

let age = 18  // 相当与设置了 类型为number
age = 'string' // 会报错

let foo  // 不赋值被推断为any  
// 建议个每个变量添加明确的类型 便于维护

TS断言

const nums = [110,120,119,112]
// 使用as关键词
const num1 = nums[1] as number
// 使用尖括号 会跟jsx混淆,不建议使用
const num2 = <number>res

TS接口(Interface)

一种规范契约 使用一种接口就要使用接口全部的规定

// 定义一个对象是什么样的
interface Post{
    title:string; 
    content:string;
}
function printPost(post:Post){
    console.log(post.title)
    console.log(post.content)
}
printPost({
    title:'Hello TypeScript',
    content:"A javascript superset"})
// 接口约束一个对象必须要有一些成员

补充

interface Post{
    title:string
    content:string
	subtitle?:string  // 表示词成员可有可无 即值为undefined 和string
    readonly summary:string // 只读成员  用readonly 关键字修饰
}
const hello:Post = {
    title:'Hello Typescript',
    content:"A javascript superset",
    summary:'A javascurpt'
}


// 动态成员
interface Cache{
    [key:string]:string
}
// 成员的键值必须是string类型的
const cache:Cache={}

描述一类具体事物的抽象特征

程序中的类指的是 用来描述一类具体对象的抽象成员

class Person{
    // ts必须先声明属性
    name:string = 'init name'
    age:number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`)
    }
}

类的访问修饰符

class Person{
    public name:string = 'init name' // 加不加都一样
    protected gender:boolean // 只允许在子类中访问的成员 可以被继承
    private age:number // 私有属性
    consrtuctor(name:string,age:number){
        this.name = name
        this.age = age
    }
    sayHi(msg:string) :void{
        console.log(`I am ${this.name},${msg}`)
        console.log(this.age)
    }
}
class Strdent extends Person{
    private constructor(name:string ,age:number){
        super(name,age)
        console.log(this.gender)
    }
    static create(name:string,age:number){
        return new Student(name,age)
    }
}


const tom = new Person('tom',18)

类的只读属性

class Person{
    public name:string
    private age:number
    protected readonly gender:boolean
    constructor(name:string,agenumber){
        this.name=name
        this.age=age
        this.gender=true
    }
    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`)
        console.log(this.age)
    }
}
const tom = new Person('tom',18)
console.log(tom.name)
// tom.gender = false

类与接口

interface EatAndRun{
    eat(food:string):void
    run(distance:number):void
}

interface Eat{
    eat(food:string):void
}

interface Run{
    run(distance:number):void
}

class Person implements EatAndRun , Run {
    eat(food:string):void{
        console.log(`优雅的进餐:${food}`)
    }
    run(distance:number):void{
        console.log(`直立行走:${distance}`)
    }
}

class Animal implements EatAndRun {
    eat(food:string):void{
        console.log(`呼噜呼噜的吃:${food}`)
    }
    run(distance:number):void{
        console.log(`爬行:${distance}`)
    }
}

抽象类

跟接口类似

不同的是可以包含一些具体的实现

abstract class Animal{
    eat(food:string):void{
        console.log(`呼噜呼噜的吃:${food}`)
    }
	abstract run (distance:number):void
}
class Dog extends Animal{
    run(distance:number):void{
        console.log(`四脚爬行:${distance}`)
    }
}

泛型

定义函数接口或类的时候,没有指定具体类型,在使用时传递一个类型

// 函数
function createNumberArray(length:number,value:number):number[]{
    const arr = Array<number>(length).fill(value)
    return arr
}
function createStringArray(length:number,value:number):string[]{
    const arr = Array<string>(length).fill(value)
    return arr
}
const res = createNumberArray(3,100)


function createArray<T>(length:number,value:T):T[]{
    const arr = Array<T>(length).fill(value)
    return arr
}
// 泛型在调用的时候用给T指定类型
const resString = createArray<string>(3,'ssd')
const resNumber = createArray<number>(3,100)

类型声明

在使用第三放模块时,并没有对应的类型限制

// 导入lodash中的camelCase 用于将字符串转换为驼峰格式
// 其中lodash会报错 没有类型限制 安装类型声明模块
import { camelCase } from 'lodash'
// 使用declare进行类型声明
declare function camelCase(input:string):string
const res = camelCase('hello typed')
// query-string url字符串声明文件

fill(value)
return arr
}
function createStringArray(length:number,value:number):string[]{
const arr = Array(length).fill(value)
return arr
}
const res = createNumberArray(3,100)

function createArray(length:number,value:T):T[]{
const arr = Array(length).fill(value)
return arr
}
// 泛型在调用的时候用给T指定类型
const resString = createArray(3,‘ssd’)
const resNumber = createArray(3,100)


# 类型声明

 在使用第三放模块时,并没有对应的类型限制

```ts
// 导入lodash中的camelCase 用于将字符串转换为驼峰格式
// 其中lodash会报错 没有类型限制 安装类型声明模块
import { camelCase } from 'lodash'
// 使用declare进行类型声明
declare function camelCase(input:string):string
const res = camelCase('hello typed')
// query-string url字符串声明文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值