After working with typescript for a while, I feel the need for typescript on medium – and large-sized projects. It avoids many bugs, such as nasty spelling problems, at compile time. And more and more packages also start to use TS, so it is imperative to learn TS.

Here are some useful typescript tips I’ve found in my work.

01 keyof

Keyof is slightly similar to object. keys, except that keyof takes the keyof interface.

interface Point {
    x: number;
    y: number;
}

// type keys = "x" | "y"
type keys = keyof Point;Copy the code
Suppose we have an object like this, and we need to use typescript to implement a get function to get its property values

const data = {
  a: 3,
  hello: 'world'
}

function get(o: object, name: string) {
  return o[name]
}Copy the code
We might write it this way at first, but it has a lot of disadvantages

  1. Unable to confirm return type: this will deprive TS of maximum type validation
  2. Unable to constrain key: possible spelling problems
You can use keyof to enhance the type function of the get function. If you are interested, you can see the type tag of _

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

02 Partial & Pick

Now that you know about keyof, you can use it to extend properties such as Partial and Pick, which is usually used in _. Pick

type Partial<T> = {
  [P inkeyof T]? : T[P]; };type Pick<T, K extends keyof T> = {
  [P inK]: T[P]; }; interface User { id: number; age: number; name: string; }; // Equivalent to:typePartialUser = { id? : number; age? : number; name? : string; }typePartialUser = Partial<User> // equivalent to:type PickUser = { id: number; age: number; }
type PickUser = Pick<User, "id" | "age">Copy the code

03 Condition Type

Similar to js? : operator that you can use to extend some primitive types

T extends U ? X : Y

type isTrue<T> = T extends true ? true : false/ / equivalent totype t = false
typeT = isTrue<numbertype t = false
type t1 = isTrue<false>Copy the code

04 never & Exclude & Omit

The official documentation describes never as follows

the never type represents the type of values that never occur.
A combination of never and conditional types can be used to introduce many interesting and useful types, such as Omit

typeExclude<T, U> = T extends U ? never : T; // Equivalent to:type A = 'a'
type A = Exclude<'x' | 'a'.'x' | 'y' | 'z'>Copy the code
Omit may be used to Omit anything

typeOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; interface User { id: number; age: number; name: string; }; // Equivalent to:type PickUser = { age: number; name: string; }
type OmitUser = Omit<User, "id">Copy the code

05 typeof

As the name implies, Typeof stands for type that takes a value, and the following example illustrates their use

Const a: number = 3 const b: number = 4 const b: typeof a = 4Copy the code
In a typical server project, we often need to plug tools into the context, such as config, Logger, DB Models, utils, etc., and use typeof.

import logger from './logger'
import utils from './utils'

interface Context extends KoaContect {
  logger: typeof logger,
  utils: typeof utils
}

app.use((ctx: Context) => {
  ctx.logger.info('hello, world'Logger.ts (ctx.loger.info); // This method is not exposed in logger.ts, so it is possible to avoid spelling error ctx.loger.info('hello, world')})Copy the code

06 is

Before we do that, let’s take a look at the KOA error handling process. Here’s how to centrally handle error and identify code

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    let code = 'BAD_REQUEST'
    if (err.isAxiosError) {
      code = `Axios-${err.code}`}else if (err instanceof Sequelize.BaseError) {

    }
    ctx.body = {
      code
    }
  }
})Copy the code
Error: Property ‘code’ does not exist on type ‘Error’. Ts (2339)

You can use as AxiosError or as any to avoid errors, but casting is not friendly either

if ((err as AxiosError).isAxiosError) {
  code = `Axios-${(err as AxiosError).code}`}Copy the code
You can use is to determine the type of the value

function isAxiosError (error: any): error is AxiosError {
  return error.isAxiosError
}

if (isAxiosError(err)) {
  code = `Axios-${err.code}`}Copy the code
In the GraphQL source code, there are many uses like this to identify types

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;Copy the code

07 interface & type

What is the difference between interface and type? Refer to the following stackOverflow question

stackoverflow.com/que…

In general, there is little difference between interface and type

interface A {
  a: number;
  b: number;
};

type B {
  a: number;
  b: number;
}Copy the code
Interface can be combined as follows, and type can only be connected using &.

interface A {
    a: number;
}

interface A {
    b: number;
}

const a: A = {
    a: 3,
    b: 4
}Copy the code

08 Dictionary & Many

These syntactic sweets are learned from the types source of Lodash, and are often used in work.

interface Dictionary<T> {
  [index: string]: T;
};

interface NumericDictionary<T> {
  [index: number]: T;
};

const data:Dictionary<number> = {
  a: 3,
  b: 4
}Copy the code

09 Maintaining regular tables using const enum

Const enums provide safer type checking than using literal objects to maintain constants

// Maintain constant with object const enum TODO_STATUS {TODO ='TODO',
    DONE = 'DONE',
    DOING = 'DOING'
}

function todos (status: TODO_STATUS): Todo[];

todos(TODO_STATUS.TODO)Copy the code

10 VS Code Tips & Typescript Command

When using VS Code, there are times when compiling with TSC causes problems that are not consistent with what VS Code prompts

Locate the Typescript word in the lower right corner of your project and display its Version number on the right. Select Use Workspace Version, which represents the Typescript Version that your project depends on.

Or edit.vs-code/settings.json

{
  "typescript.tsdk": "node_modules/typescript/lib"
}Copy the code

11 Typescript Roadmap

Last but not least, look into the Roadmap for new FEATURES and bug fixes for TS.