概述
- 静态类型与动态类型
- 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
移除类型注解
- 通过flow官方的flow-remove-types模块
安装
yarn add flow-remove-types --dev
移除
// . 当前目录下的文件 输出到 dist 目录下
yarn flow-remove-types . -d dist
- 通过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 类型推断
类型注解
// 函数返回值
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运行环境api
const el:HTMlElement| null = document.getElementById('app')
api对应的声明文件的连接
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字符串声明文件
今天的文章TypeScript语言分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/27925.html