• 推荐 7 个 GitHub 上很火的 TypeScript 的宝库


    官网上有什么是 TypeScript,为什么要用 TypeScript ,和 api 相关的文档,而且还是一手的学习资料,无疑是最好的学习资料了。

    网站 说明
    TypeScript TypeScript 官网,TS 扩展了 JavaScript ,为它添加了类型支持
    typescript-tutorial TypeScript 入门教程,循序渐进的理解 TypeScript
    TypeScript 手册 TypeScript 使用手册
    typescript-book-chinese 深入理解 TypeScript
    clean-code-typescript 适用于TypeScript的简洁代码概念
    TypeScript入门 TypeScript 入门的视频教程
    typescript-tutorial TypeScript 速成教程(2小时速成)

    TypeScript 高级技巧

    用了一段时间的 typescript 之后,深感中大型项目中 typescript 的必要性,它能够提前在编译期避免许多 bug,如很恶心的拼写问题。而越来越多的 package 也开始使用 ts,学习 ts 已是势在必行

    1、keyof keyofObject.keys 略有相似,只不过 keyofinterface 的键

    interface Point {
        x: number;
        y: number;
    }
    
    // type keys = "x" | "y"
    type keys = keyof Point;
    

    可以使用 keyof 来加强 get 函数的类型功能

    function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
      return o[name]
    }
    
    

    2、 Required & Partial & Pick 这个都是typescript内置的函数

    type Partial<T> = {
      [P in keyof T]?: T[P];
    };
    
    type Required<T> = {
      [P in keyof T]-?: T[P];
    };
    
    type Pick<T, K extends keyof T> = {
      [P in K]: T[P];
    };
    
    interface User {
      id: number;
      age: number;
      name: string;
    };
    
    // 相当于: type PartialUser = { id?: number; age?: number; name?: string; }
    type PartialUser = Partial<User>
    
    // 相当于: type PickUser = { id: number; age: number; }
    type PickUser = Pick<User, "id" | "age">
    
    

    3、Condition Type 类似于 js 中的 ?: 运算符,可以使用它扩展一些基本类型

    T extends U ? X : Y
    
    type isTrue<T> = T extends true ? true : false
    // 相当于 type t = false
    type t = isTrue<number>
    
    // 相当于 type t = false
    type t1 = isTrue<false>
    

    4、 never & Exclude & Omit

    结合 never 与 conditional type 可以推出很多有意思而且实用的类型

    type Exclude<T, U> = T extends U ? never : T;
    
    // 相当于: type A = 'a'
    type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>
    

    结合 Exclude 可以推出 Omit 的写法

    type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
    
    interface User {
      id: number;
      age: number;
      name: string;
    };
    
    // 相当于: type PickUser = { age: number; name: string; }
    type OmitUser = Omit<User, "id">
    

    5、 typeof 顾名思义,typeof 代表取某个值的 type,可以从以下示例来展示他们的用法

    6、 is 使用 is 来判定值的类型

    export function isType(type: any): type is GraphQLType;
    
    export function isScalarType(type: any): type is GraphQLScalarType;
    
    export function isObjectType(type: any): type is GraphQLObjectType;
    
    export function isInterfaceType(type: any): type is GraphQLInterfaceType;
    

    7、 interface & type interface 可以如下合并多个,而 type 只能使用 & 类进行连接。

    8、 Record & Dictionary & Many typescript语法糖

    type Record<K extends keyof any, T> = {
        [P in K]: T;
    };
    
    interface Dictionary<T> {
      [index: string]: T;
    };
    
    interface NumericDictionary<T> {
      [index: number]: T;
    };
    
    const data:Dictionary<number> = {
      a: 3,
      b: 4
    }
    
    
    

    9、 enum 维护常量表

    const enum TODO_STATUS {
      TODO = 'TODO',
      DONE = 'DONE',
      DOING = 'DOING'
    }
    
    function todos (status: TODO_STATUS): Todo[];
    
    todos(TODO_STATUS.TODO)
    
    

    巧用 Typescript(一)

    巧用注释 通过/** */形式的注释可以给 TS 类型做标记,编辑器会有更好的提示:

    注释有很多规范的字段 ,但不用着急翻文档,在 /** */ 里输入 @ 就可以看到丰富的选择

    /** A cool guy. */
    interface Person {
      /** A cool name. */
      name: string,
    }
    

    巧用 typeof

    我们一般先写类型,再使用:

    interface Opt {
      timeout: number
    }
    const defaultOption: Opt = {
      timeout: 500
    }
    

    有时候可以反过来:

    const defaultOption = {
      timeout: 500
    }
    type Opt = typeof defaultOption
    

    巧用联合类型

    //   Not good.
    interface Dinner1 {
      fish?: number,
      bear?: number,
    }
    
    //   Awesome!
    type Dinner2 = {
      fish: number,
    } | {
      bear: number,
    }
    

    巧用查找类型

    interface Person {
      addr: {
        city: string,
        street: string,
        num: number,
      }
    }
    

    当需要使用 addr 的类型时,除了把类型提出来

    interface Address {
      city: string,
      street: string,
      num: number,
    }
    interface Person {
      addr: Address,
    }
    

    还可以

    Person["addr"] // This is Address.
    

    巧用查找类型+泛型+keyof

    interface API {
      '/user': { name: string },
      '/menu': { foods: Food[] },
    }
    const get = <URL extends keyof API>(url: URL): Promise<API[URL]> => {
      return fetch(url).then(res => res.json())
    }
    

    极大的增强了代码的提示性

    巧用显式泛型

    $('button') 是个 DOM 元素选择器,可是返回值的类型是运行时才能确定的,除了返回 any ,还可以

    function $<T extends HTMLElement>(id: string):T {
      return document.getElementById(id)
    }
    
    // Tell me what element it is.
    $<HTMLInputElement>('input').value
    

    巧用 DeepReadonly

    type DeepReadonly<T> = {
      readonly [P in keyof T]: DeepReadonly<T[P]>;
    }
    
    const a = { foo: { bar: 22 } }
    const b = a as DeepReadonly<typeof a>
    b.foo.bar = 33 // Hey, stop!
    

    巧用 Omit

    import { Button, ButtonProps } from './components/button'
    
    type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
    type BigButtonProps = Omit<ButtonProps, 'size'>
    
    function BigButton(props: BigButtonProps) {
      return Button({ ...props, size: 'big' })
    }
    

    巧用Record类型

    业务中,我们经常会写枚举和对应的映射:

    type AnimalType = 'cat' | 'dog' | 'frog';
    const AnimalMap = {
      cat: { name: '猫', icon: ' '},
      dog: { name: '狗', icon: ' ' },
      forg: { name: '蛙', icon: ' ' },
    };
    

    注意到上面 forg 拼错了吗?Record 可以保证映射完整:

    type AnimalType = 'cat' | 'dog' | 'frog';
    interface AnimalDescription { name: string, icon: string }
    const AnimalMap: Record<AnimalType, AnimalDescription> = {
      cat: { name: '猫', icon: ' '},
      dog: { name: '狗', icon: ' ' },
      forg: { name: '蛙', icon: ' ' }, // Hey!
    };
    

    如果你喜欢用 enum ,写法也一样的

    
    enum AnimalType {
      CAT = 'cat',
      DOG = 'dog',
      FROG = 'frog',
    }
    const AnimalMap: Record<AnimalType, AnimalDescription>
    

    巧用Partial

    就是部分的意思,很常用的。

    const mergeOptions = (options: Opt, patch: Partial<Opt>) {
      return { ...options, ...patch };
    }
    
    class MyComponent extends React.PureComponent<Props> {
      defaultProps: Partial<Props> = {};
    }
    

    巧用tsx+extends

    在 .tsx 文件里,泛型可能会被当做 jsx 标签

    const toArray = <T>(element: T) => [element]; // Error in .tsx file.
    

    加 extends 可破

    const toArray = <T extends {}>(element: T) => [element]; // No errors.
    

    巧用ClassOf

    有时候,我们要传入类本身,而不是类的实例

    abstract class Animal extends React.PureComponent {
      /* Common methods here. */
    }
    class Cat extends Animal {}
    class Dog extends Animal {}
    
    // `AnimalComponent` must be a class of Animal.
    const renderAnimal = (AnimalComponent: Animal) => {
      return <AnimalComponent/>; // WRONG!
    }
    

    上面的代码是错的,因为 Animal 是实例类型,不是类本身。应该

    interface ClassOf<T> {
      new (...args: any[]): T;
    }
    const renderAnimal = (AnimalComponent: ClassOf<Animal>) => {
      return <AnimalComponent/>; // Good!
    }
    
    renderAnimal(Cat); // Good!
    renderAnimal(Dog); // Good!
    
  • 相关阅读:
    Hadoop的运行痕迹
    生活常识
    hadoop集群崩溃恢复记录
    Hadoop_NameNode_代码分析_目录树(2)
    .NET Is 和 As 的区别
    hadoop集群管理之 SecondaryNameNode和NameNode
    sql2005分页存储过程原创
    c#生成json数据 JavaScript对json数据处理
    LVS改变ConnectionHashtable值
    MySQL Cluster集群配置
  • 原文地址:https://www.cnblogs.com/boyGdm/p/14449277.html
Copyright © 2020-2023  润新知