• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

TypeScript学习笔记

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

文章内容输出来源:拉勾教育大前度高薪训练营

typeScript:javaScript的超集(superet)

typeScript 概述

  • 所谓超级是指:一套更加强大的类型系统,和对es6新特性的支持, 最终会编译成javaScript;
  • 作用:帮我们避免编码中出现的类型异常,提高我们编码的效率以及我们代码的可靠程度;
  • 兼容性:最低可编译到es3版本, 兼容性较好;
  • 任何一种JavaScript运行环境都支持;
  • 相较于folw,typeScript功能更为强大,生态也更健全、更完善;
  • 目前angular/vue3已经开始使用typeScript;
  • 你会发现typeScript慢慢的将成为前端领域中的第二语言;
  • 缺点:
    1. 语法本身多了很多概念(typescript属于「渐进式」的);
    2. 项目初期,typeScript会增加一些成本;

typeScript快速上手

  1. 安装:

    • 初始化package.json -- 命令:yarn init -y
    {
    "name": "typeScript",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT"
    }
    • 安装开发依赖:yarn add typescript -D
    {
    "name": "typescript",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "devDependencies": {
    "typescript": "^4.1.3"
    }
    }
    • tsc的作用:用于编译typescript
    • 可以完全按照JavaScript标准语法编译代码
    • 代码示例:

      • 编译前:

        const hello = name => {
                    console.log(`hello ${name}`);
        }
        hello('typeScript');
      • 编译后:

        var hello = function (name) {
            console.log("hello " + name);
        };
        hello('typeScript');
    • ts初使用:

        const hello = (name: string) => {
              console.log(`hello ${name}`);
      }
      // hello('typeScript');
      hello(100);

    typeScript配置文件

    • 创建typescript配置文件:yarn tsc --init
    • 使用tsconfig编译ts文件:yarn tsc
    {
        "compilerOptions": {
    /* 访问https://aka.ms/tsconfig.json以了解有关此文件的更多信息 */
    /* 基本选项 */
    // "incremental": true, /* 启用增量编译 */
    "target": "es5", /* 指定ECMAScript目标版本:``ES3''(默认),``ES5'',``ES2015'',``ES2016'',``ES2017'',``ES2018'',``ES2019'',``ES2020''或``ESNEXT''。 */
    "module": "commonjs", /* 指定模块代码生成:“ none”,“ commonjs”,“ amd”,“ system”,“ umd”,“ es2015”,“ es2020”或“ ESNext”。 */
    // "lib": [], /* 指定要包含在编译中的库文件 */
    // "allowJs": true, /* 允许编译javascript文件。 */
    // "checkJs": true, /* 报告.js文件中的错误。 */
    // "jsx": "preserve", /* 指定JSX代码生成:'preserve''react-native'或'react'。 */
    // "declaration": true, /* 生成相应的'.d.ts'文件。 */
    // "declarationMap": true, /* 为每个相应的'.d.ts'文件生成一个源映射。*/
    // "sourceMap": true, /* 生成相应的'.map'文件。*/
    // "outFile": "./", /* 连接并输出到单个文件。*/
    // "outDir": "./", /* 将输出结构重定向到目录。 */
    // "rootDir": "./", /* 指定输入文件的根目录。用于通过--outDir控制输出目录结构。 */
    // "composite": true, /* 启用项目编译 */
    // "tsBuildInfoFile": "./", /* S指定用于存储增量编译信息的文件 */
    // "removeComments": true, /* 不输出注释。 */
    // "noEmit": true, /* 不发出输出。 */
    // "importHelpers": true, /* 从'tslib'导入导入发射助手。*/
    // "downlevelIteration": true, /* 在以'ES5'或'ES3'为目标时,以'for-of',散布和解构形式提供对Iterables的全面支持。*/
    // "isolatedModules": true, /* 将每个文件作为单独的模块进行编译(类似于'ts.transpileModule')。 */
    /* 严格的类型检查选项 */
    "strict": true, /* 启用所有严格的类型检查选项。 */
    // "noImplicitAny": true, /* 在隐式“ any”类型的表达式和声明上引发错误。 */
    // "strictNullChecks": true, /* 启用严格的null检查。*/
    // "strictFunctionTypes": true, /* 启用对函数类型的严格检查*/
    // "strictBindCallApply": true, /* 在函数上启用严格的“ bind”,“ call”和“ apply”方法。 */
    // "strictPropertyInitialization": true, /* 在类中启用对属性初始化的严格检查。 */
    // "noImplicitThis": true, /* 在隐含'any'类型的'this'表达式上引发错误。 */
    // "alwaysStrict": true, /* 以严格模式解析,并对每个源文件发出“ use strict”。 */
    /* 其他检查*/
    // "noUnusedLocals": true, /* 报告未使用的本地错误。 */
    // "noUnusedParameters": true, /* 报告未使用参数的错误。 */
    // "noImplicitReturns": true, /* 当并非函数中的所有代码路径都返回值时,报告错误。 */
    // "noFallthroughCasesInSwitch": true, /* 在switch语句中报告失败情况的错误。 */
    // "noUncheckedIndexedAccess": true, /* 在索引签名结果中包括“ undefined” */
    /* 模块分辨率选项*/
    // "moduleResolution": "node", /* 指定模块解析策略:'node'(Node.js)或'classic'(TypeScript 1.6之前的版本)。*/
    // "baseUrl": "./", /* 用于解析非绝对模块名称的基目录。*/
    // "paths": {}, /* 一系列条目,这些条目将导入重新映射到相对于'baseUrl'的查找位置。 */
    // "rootDirs": [], /* 根目录列表,其组合内容表示运行时项目的结构。*/
    // "typeRoots": [], /* 要包括其类型定义的文件夹列表。 */
    // "types": [], /* 要包含在编译中的类型声明文件。 */
    // "allowSyntheticDefaultImports": true, /* 允许从默认导入模块,而没有默认导出。这不影响代码发出,仅影响类型检查。 */
    "esModuleInterop": true, /* 通过为所有导入创建名称空间对象来启用CommonJS和ES模块之间的发射互操作性。暗示“ allowSyntheticDefaultImports”。 */
    // "preserveSymlinks": true, /* 不解析符号链接的真实路径。 */
    // "allowUmdGlobalAccess": true, /* 允许从模块访问UMD全局变量。 */
    /* 源映射选项 */
    // "sourceRoot": "", /* 指定调试器应在其中定位TypeScript文件的位置,而不是源位置。 */
    // "mapRoot": "", /* 指定调试器应定位地图文件的位置,而不是生成的位置。 */
    // "inlineSourceMap": true, /* 发出带有源映射的单个文件,而不是单独的文件。 */
    // "inlineSources": true, /* 在单个文件中将源代码与源映射一起发射出去;需要设置“ --inlineSourceMap”或“ --sourceMap”。*/
    /* 实验选项 */
    // "experimentalDecorators": true, /* 启用对ES7装饰器的实验性支持。 */
    // "emitDecoratorMetadata": true, /* 启用实验性支持以发出装饰器的类型元数据。 */
    /* 高级选项 */
    "skipLibCheck": true, /* 跳过声明文件的类型检查。 */
    "forceConsistentCasingInFileNames": true /* 禁止对同一文件使用大小写不一致的引用。 */
    }
    }

原始类型:Primitive Types

/**
 * 原始数据类型
 */
const a: string = "foobar";
const b: number = 100 // NaN Infinity
const c: boolean = true // false

// const d: boolean = null // 严格模式下string/boolean/number不允许为空

const e: void = undefined // null  // 严格模式下只能是undefined

const f: null = null

const g: undefined = undefined;

typeScript标准库声明

  1. Symbol()为es6新增
  2. 使用方法:
    • 第一种:修改"target"为 "es2015"
    • 第二种:添加"lib": [ "ES2015","DOM" ]
/**
 * Symbol()为es6新增
 */
const h: symbol = Symbol();
  1. 标准库就是内置对象所对应的声明

typeScript中文错误信息

  • 第一种方法:yarn tsc --locale zh-CN

  • 第二种方法:

typeScript 作用域问题

// 作用域问题

const a = 123; // 无法重新声明块范围变量“a”。报错原因:全局作用上已经有a变量
/**
 * 解决方法1:将变量放到立即执行函数当中
 */
(function () {
    const a = 123;
})()

/**
 * 解决方法2:以模块的方式使用
 */
const a = 123;

export { }

typeScript Object类型

// object 类型

export { } // 确保跟其他示例没有成员冲突

const foo: object = function () { } //[] //{}

const obj: { foo: number, bar: string } = { foo: 11, bar: 'string' }

typeScript数组类型

// 数组类型

export { } // 确保跟其他示例没有成员冲突

const arr1: Array<number> = [12, 23, 4];

const arr2: number[] = [1, 2, 3];


//--------------
function sum(...args: number[]) {
    return args.reduce((prev, current) => prev + current, 0)
}

sum(1, 2, 3)

元组类型 Tuple Types

  • 数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
  • 元组起源于函数编程语言(如 F#),这些语言中会频繁使用元组。
// 元组 Tuple

export { } // 确保跟其他示例没有成员冲突

const tuple: [number, string] = [12, 'zce'];

// const age = tuple[0];
// const name = tuple[1];

const [age, name] = tuple;// 数组解构的方式获取值

// ----------

Object.entries({
    foo: 123,
    bar: '34'
})

typeScript 枚举类型

  • 枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。
// 枚举 Enum

export { } // 确保跟其他示例没有成员冲突
// const PostStatus = {
//     Draft: 0,
//     Unpublished: 1,
//     Published: 2
// }


// 自动添加值
// enum PostStatus {
//     Draft = 0,
//     Unpublished = 1,
//     published = 2
// }

// 默认值 0 1 2 
// enum PostStatus {
//     Draft,
//     Unpublished,
//     published
// }

// 从第一个开始自增
// enum PostStatus {
//     Draft = 5,
//     Unpublished,
//     published
// }

// 值为字符串 
// enum PostStatus {
//     Draft = "aaa",
//     Unpublished = "bbb",
//     published = "ccc"
// }

const enum PostStatus {
    Draft,
    Unpublished,
    published
}
const post = {
    title: "Hello TypeScript",
    content: "TypeScript is a typed superset of JavaScript",
    status: PostStatus.Draft
}

TypeScript 函数类型

// 函数类型

export {}; // 确保跟其他示例没有成员冲突

// function func1(a: number, b: number): string {
//   return 'func1';
// }
// func1(100, 200);
// func1(100);
// func1(100, 200, 300);

// 参数可选
// function func1(a: number, b?: number): string {
//   return 'func1';
// }
// func1(100, 200);
// func1(100);
// func1(100, 200, 300);

// 默认参数s
// function func1(a: number, b: number = 200): string {
//   return 'func1';
// }
// func1(100, 200);
// func1(100);
// func1(100, 200, 300);

// 默认参数
// function func1(a: number, b: number = 200): string {
//   return 'func1';
// }
// func1(100, 200);
// func1(100);
// func1(100, 200, 300);

// 任意参数
// function func1(a: number, b: number = 200, ...rest: number[]): string {
//   return 'func1';
// }
// func1(100, 200);
// func1(100);
// func1(100, 200, 300);

// 函数表达式所对应的限制
const func2: (a: number, b: number) => string = function (
  a: number,
  b: number
): string {
  return 'func2';
};

TypeScript 任意类型

// 任意类型

export {}; // 确保跟其他示例没有成员冲突

function stringfy(value: any) {
  return JSON.stringify(value);
}

stringfy('string');

stringfy(100);

stringfy(true);

let foo: any = 'string';

foo = 100;

foo.bar();

// any类型是不安全的

TypeScript 隐式类型推断

// 隐式类型推断

/**
 * Age => 年龄
 *  let age: number
 * 不能将类型“string”分配给类型“number”。
 */
let age = 18;
// age = 'string';

类型断言

// 类型断言 

export {}; // 确保跟其他示例没有成员冲突

// 假定这个nums 来自一个明确的接口
const nums = [110, 120, 119, 112];

const res = nums.find((i) => i > 0);

// const square = res * res;

const num1 = res as number; // 断言as

const num2 = <number>res; // 断言<number>   JSX下不能使用

TypeScript 接口

// 接口

export {}; // 确保跟其他示例没有成员冲突

// 接口定义
// interface Post {
//   title: string;
//   content: string;
// }

// function printPost(post: Post) {
//   console.log(post.title);
//   console.log(post.content);
// }
// printPost({ title: '111', content: '2222' });
// ----------
interface Post {
  title: string;
  content: string;
  subtitle?: string; // 可选
  readonly summary: string; // 只读
}
const hello: Post = {
  title: "Hello TypeScript",
  content: "a JavaScript Supperset",
  summary: "a JavaScript",
};

// ------------
interface Cache {
  [prop: string]: string;
}

const cache: Cache = {};
cache.value = "value";
cache.foo = "foo";

TypeScript 类的基本使用

  • 描述一类具体事物的抽象特征,例如:手机
  • 用来描述一类具体对象的抽象成员
  • ES6以前, 都是通过函数+原型模拟实现类
  • ES6开始,Javascript中有了专门的class
  • TypeScript增强了class的相关语法
// 类 class

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

  sayHi(msg: string): void {
    console.log("I am ${this.name},${this.age}");
  }
}

TypeScript 类的访问修饰符

// 类的访问修饰符
export {};
class Person {
  public name: string;
  private age: number;
  protected gender: boolean;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    this.gender = true;
  }

  sayHi(msg: string): void {
    console.log("I am ${this.name},${this.age}");
  }
}

class Student 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);
console.log(tom.name);
// console.log(tom.age);// age为私有成员
// console.log(tom.gender);

// const jack = new Student(); // private只允许在内部使用
const jack = Student.create("jack", 18); // 通过static访问

TypeScript 类的只读属性

// 只读属性 readonly
export {};
class Person {
  public name: string;
  private age: number;
  protected readonly gender: boolean;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    this.gender = true;
  }

  sayHi(msg: string): void {
    console.log("I am ${this.name},${this.age}");
  }
}

const tom = new Person("tom", 18);
console.log(tom.name);
// tom.gender = false;

TypeScript 类与接口

// 类与接口

export {};

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

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

// --------------

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

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

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

TypeScript 抽象类

// 抽象类

export {};

abstract class Animal {
  eat(food: string): void {
    console.log(`呼噜呼噜的吃:${food}`);
  }
  abstract run(distance: number): void;
}

class Dog extends Animal {
  run(distance: number): void {
    throw new Error("Method not implemented.");
  }
}

const d = new Dog();

d.eat("的说法");
d.run(100);

TypeScript 泛型

//泛型
export {};

function createNumberArray(length: number, value: number): number[] {
  const arr = Array<number>(length).fill(value);
  return arr;
}
function createStringArray(length: number, value: string): string[] {
  const arr = Array<string>(length).fill(value);
  return arr;
}

function createArray<T>(length: number, value: T): T[] {
  const arr = Array<T>(length).fill(value);
  return arr;
}

// const res = createNumberArray(3, 100); //res => [100,100,100]

const res = createArray<string>(2, "foo");

TypeScript 类型声明

// 类型声明
import { camelCase } from "lodash";

import qs from "query-string";

qs.parse("?key=value&key2=value2");
// declare function camelCase(input: string): string;
const res = camelCase("hello Typed");


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap