preface

This article is a personal summary of learning TypeScript. It mainly introduces some important and common points, as well as some problems that are not easy to understand. At the same time, it also references some online articles, hoping to help beginners get started quickly

type

The base type

  • Number: includes floating point numbers, NaN, ±Infinity.
  • String: a string.
  • Boolean: Boolean, i.e. {true, false}.
  • Null: {null}.
  • Undefined: {undefined}. By default, null and undefined are subtypes of all types and can be assigned to any type; When you specify strictNullChecks, null and undefined can only be assigned to void and their respective checks
  • Symbol: symbol type.
  • Never: indicates an endpoint that can never be reached. It is a subtype of any type and can be assigned to any type, but cannot be assigned to any type except itself. A function that throws an error or has an infinite loop will never return a value of type never
  • Void: indicates that there is no type and no return value. It is equal to {null, undefined}.
  • Tuple: a special array that specifies the specific type of each item in the array. eg: let tuple1: [number, string] = [12, ‘aa’]
  • Enumeration (enum) : A specific mapping with a fixed set of values. Eg: enum sex {MALE, FEMALE} equal to enum sex {MALE=0, FEMALE=1} sex.MALE // value
  • Any type (any)
  • unknow
  • Object means a non-primitive type, that is, a type other than number, String, Boolean, symbol, NULL, or undefined. In addition, all primitive literals can also be used as types themselves, and their extension includes only themselves

High-level types

  • A union type means that a value can be one of several types, equivalent to an intersection of sets. A vertical bar (|) separated; If a value is a union type, only members common to all types of that union type can be accessed

  • A cross type merges multiple types into a single type, equivalent to a set union. Vertical line (&) separation; Existing types are superimposed into a single type that contains all the required features of the type and is used mostly for mixins

  • Mapping type: a way to create a new type from an old type (including Readonly Partial Record Pick)

        type Readonly<T> = {
            readonly [P in keyof T]: T[P];
        }
        type Partial<T> = {
            [P inkeyof T]? : T[P]; }interface Person {
            name: string;
            age: number;
        }
    
        / / call
        type PersonPartial = Partial<Person>;
        type ReadonlyPerson = Readonly<Person>;
    Copy the code
        / / the result
        typePersonPartial = { name? :string|undefined; age? :number|undefined;
        }
        type PersonReadonly {
            readonly name: string;
            readonly age: number;
        }
    Copy the code

Type of protection

  1. User-defined Type protection: defines functions and returns Type predicates (syntax: parameterName is Type)

  2. Typeof type protection: only two types can be recognized typeof V === “typename” and typeof V! == “typename”, “typename” must be a primitive type of “number”, “string”, “Boolean”, or “symbol”. Strings other than the first four are not recognized as type-protected

  3. Instanceof type protection: A way to refine types by using constructors. Syntax: Instance instanceof constructor

       function pluck<T.K extends keyof T> (o: T, names: K[]) :T[K] []{
         return names.map(n= > o[n]);
       }
       
       interface Person {
           name: string;
           age: number;
       }
       let person: Person = {
           name: 'Jarid',
           age: 35
       };
       let strings: string[] = pluck(person, ['name']); // ok, ['Jarid]
    Copy the code

    Keyof T, index type query operators (in this instance, for person’s attribute name, age, value is equal to the ‘name’ | ‘age’) K extends keyof T, T [K], generic constraint index access operator (in this instance, as the person [‘ name ‘])

Summary :(the following pictures are from the network, thank you ~)

The generic

Generics is the property of defining functions, interfaces, or classes without specifying a specific type in advance, but specifying the type at the time of use. Type variables (type parameters) are typically represented by T

Generalized constraint extends

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise> (arg: T) :T {
    console.log(arg.length);
    return arg;
}
Copy the code

A generic interface

Use interfaces with generics to define function shapes

    interface ConfigFn{
        <T>(value:T):T;
    }

    var getData:ConfigFn=function<T> (value:T) :T{
        return value;
    }

    getData<string> ('Joe');
    getData<string> (1243);  / / error
Copy the code
Interface ConfigFn<T>{(value:T):T; } var getData:ConfigFn<string>=function<T>(value:T):T{
        return value;
    }

    getData('20'); Interface ConfigFn<T>{(value:T):T; }function getData<T>(value:T):T{
        return value;
    }
    
    var myGetData:ConfigFn<string>=getData;     
    myGetData('20'); /* Correct */ myGetData(20) // errorCopy the code

A generic class

Use generics to define classes

  class GenericNumber<T> {
      zeroValue: T;
      add: (x: T, y: T) = > T;
  }

  let myGenericNumber = new GenericNumber<number> (); myGenericNumber.zeroValue =0;
  myGenericNumber.add = function(x, y) { return x + y; };
Copy the code

class

Abstract classes, abstract methods, inheritance relationships

  • An abstract class
An abstract class is a base class that provides inheritance from other classes and cannot be instantiated directly. An abstract method in an abstract class contains no concrete implementation and must be implemented in a derived class. However, classes with abstract methods must be declared as abstract classes.Copy the code
  • A polymorphic parent class defines a method not to be implemented, but to be implemented by subclasses that inherit it, each with a different representation (for inheritance).

Note:

1. Using polymorphic basis is class inheritance or interface implementation. 2. If a subclass inherits an abstract class, the subclass must implement an abstract method from the parent class. Otherwise, it cannot instantiate and an error will be reported. 3. A polymorphic subclass inherits its parent class. A subclass may not implement the method, but it uses polymorphism to implement the methodCopy the code

Typeof Class constructor

class Greeter {
static standardGreeting = "Hello, there"; // Static attributes
greeting: string;
greet() {
    if (this.greeting) {
        return "Hello, " + this.greeting;
    } else {
        returnGreeter.standardGreeting; }}}// typeof Greeter: the typeof a constructor that contains the class's static members and constructor
let greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!";

// Greeter: Instance type
let greeter2: Greeter = new greeterMaker();
console.log(greeter2.greet());
Copy the code

interface

In object-oriented programming, an interface is a specification definition that defines the specification of behavior and actions. An interface defines the specification that a batch of classes need to comply with. It does not care about the internal state data of these classes and the implementation details of the methods in these classes. It only specifies that certain methods must be provided in this batch, and the classes that provide these methods can meet the actual needs.

  • Object-oriented languages: Interfaces are abstractions of behavior and actions that need to be implemented by classes.
  • Ts: Abstract part of the behavior of the class and describe the shape of the object; Abstract common objects from different classes as interfaces, which are implemented separately by classes (Implement). Compared with object-oriented languages, more flexible interface types are added, including properties, functions, indexable and classes. In short, define normative standards for reuse (as opposed to plain type constraints).
interface Person {
    readonly id: number; // Read-only attribute
    name: string; // Determine the attributeage? :number; // Optional attribute
    [propName: string] :string; // String index
    [index: number] :string; // Numeric index, similar to array
    (name: string, age: number) :void; / / function
    getName(id: number) :string; / / method
    new(name: string, age: number): Person; // constructor
}
Copy the code

Note: 1. The above shows only the functions supported by the interface, not all of them can be written together. If both a numeric index and a string index exist, the numeric index’s return value must be a subtype of the string index’s return value type. Because when you index with number, JavaScript converts it to a string and then indexes object 3. String indexes exist with other attributes, and the other attribute value types must be subtypes of the string index return value type. Because string indexes declare both obj.property and obj[” property “]

Class types

Classes implement interfaces that explicitly force a class to conform to a contract

// The instance section of the interface description class
interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) {}// Class static part
}
Copy the code

The difference between the static and instance parts of a class

Classes are divided into static and instance sections:

  • The constructor and all static members of the static part class
  • Instance properties and instance methods of the instance part class are on the stereotype chain of the constructor

When you define an interface with a constructor signature and try to define a class that implements the interface, you get an error because when a class implements an interface, only the instance part is type-checked. Constructor exists in the static part of the class and is therefore outside the scope of inspection. If you want to constrain the constructor and instance parts when implementing an interface, you can constrain them separately and generate the instance through a new constructor (createClock)

// ClockConstructor for use by the constructor
// ClockInterface is used by the instance method
// The first argument to createClock is of type ClockConstructor. In createClock(AnalogClock, 7, 32), AnalogClock matches the constructor signature.
interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

// The first parameter, ctor, is of type ClockConstructor, which specifies the interface to be implemented for the static part of the class
function createClock(ctor: ClockConstructor, hour: number, minute: number) :ClockInterface {
    return new ctor(hour, minute);
}

// The object instantiated by the DigitalClock class (the instance part of the class) should satisfy the rules of this interface
class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep"); }}class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock"); }}let digital = createClock(DigitalClock, 12.17);
let analog = createClock(AnalogClock, 7.32);
Copy the code

Mixed type

Interface Counter {(start: number): string}let counter: Counter
counter = function(start: number) {console.log(number)}Copy the code
Interface Counter {interval: number; reset(): void; }Copy the code

In the official example below, the mixed type is equivalent to merging the two interfaces declared above

// An object can be used as both a function and an object, with additional attributes. Interface Counter {(start: number): string; // Function interval: number; Reset (): void; // Object method}functionGetCounter (): Counter {// Convert the function object to Counter by type assertion. The converted object not only implements the description of the function interface, making it a function, but also has the interval attribute and reset() methodlet counter = <Counter>function (start: number) { console.log(number) }; 
    counter.interval = 123;
    counter.reset = function() {};return counter;
}

letc = getCounter(); c(10); c.reset(); C.i nterval = 5.0;Copy the code

Mixed types are mainly used in libraries like UMD, such as jQuery, which can be used as functions and objects. Recently, I saw the source code of Vue3, which also exists, as follows:

export interface ReactiveEffect<T = any> {
  (): T
  _isEffect: true
  active: boolean
  raw: () => T
  deps: Array<Dep>
  options: ReactiveEffectOptions
}

function createReactiveEffect<T = any>(
  fn: () => T,
  options: ReactiveEffectOptions
): ReactiveEffect<T> {
  const effect = functionreactiveEffect(... args: unknown[]): unknown {return run(effect, fn, args)
  } as ReactiveEffect
  effect._isEffect = true
  effect.active = true
  effect.raw = fn
  effect.deps = []
  effect.options = options
  return effect
}
Copy the code

Classes and interfaces

  • Class extends Class
  • Class implements Interface
  • Interface extends Interface
  • Interface Extends Class

Ps: Here is mainly about the interface inheritance class, other we should understand, or can refer to the documentation

Interface inheritance class

When an interface inherits a class, it inherits all the members of the class but not the implementation

  class Person {
      type} interface Child extends Person {// ️Child extends Person from the Person classtypeattributelog(): void // There is actually onetypeThe Child interface above inherits the Person pairtypeAlso defines the Child interface itselflogClass Girl implements Child {class Girl implements Child {type: 'child'// The interface inherits from PersonlogClass Boy extends Person implements Child {// This extends Person class implements Childtype: 'child'
      log() {}}Copy the code

When an interface inherits a class with private or protected members, the interface type can only be implemented by that class or its subclasses (Implement).

  class Person {
      private type} interface Child extends Person {// ️Child extends Person from the Person classtypeattributelog(): void // There is actually onetypeThe Child interface above inherits the Person pairtypeAlso defines the Child interface itselflogClass Boy extends Person implements Child {class Boy extends Person implements Child {class Boy implements Persontype: 'child'
      log() {}}Copy the code

In general, this pattern should be avoided (not recommended), especially if the class has private members.

function

Define a function

1. Function declaration

function sum(x: number, y: number): number {
    return x + y;
}
Copy the code

2. Function expressions

  let mySum = function (x: number, y: number) :number {
      return x + y;
  };

  / / or
  let mySum: (x: number, y: number) = > number = function (x: number, y: number) :number {
      return x + y;
  };
Copy the code

Note: 1. Optional parameters (? : Must be followed by mandatory parameters. 2. Default value: 3. Remaining parameters (… Rest): Must be at the end, same as ES6

overloading

Overloading in Java: functions with the same name and different arguments. Overloading in typescript: A function body implements multiple functions by providing multiple function type definitions for the same function. Ts is written differently for ES5 compatibility and ES6 overloading than in Java.

functionreverse(x: number): number; // Function definitionfunctionreverse(x: string): string; // Function definitionfunctionReverse (x: number | string) : number | string {/ / function implementationif (typeof x === 'number') {
      return Number(x.toString().split(' ').reverse().join(' '));
  } else if (typeof x === 'string') {
      return x.split(' ').reverse().join(' '); }}Copy the code

Note:

1. Overload is required if the result is not the same as the parameter. Union type 2 is used. In addition, the order of overloading should match from small to large, because overloading matches from top to bottom and no longer looks down after a matchCopy the code

Configuration file tsconfig.json

Specify compilation options and project files to be compiled, including the following options:

  • CompilerOptions configures compilation options
  • Files Specifies the file to be compiled
  • Include: specifies the file to be compiled
  • Exclude: excludes files to be compiled

TS file means a file with an extension named.ts,.tsx, or.d. TS. If compileroptions. allowJs is enabled, the.js and.jsx files are also TS files

Options related to the file to be compiled

1. If files and include are not set, the compiler will include all TS files in the path except for exclude files by default. If files and include are set at the same time, the compiler will include files specified by both. If exclude is not set, the default value is node_modules, bower_components, jSPM_packages, and the path specified by the compilation option outDir. 4. Exclude only applies to include. Not valid for files 5. {"compilerOptions": {
       "typeRoots" : ["./typings"], / /typePackages in the directory specified by Roots will be compiled"types": ["node"."lodash"."express"] // Specify the compiled package}}Copy the code

Options in compilerOptions

--target: specifies the compiled js version --lib: specifies the libraries included in the compilation // Other references to official documentationCopy the code

Points to note:

1. When you call TSC without any input files, the compiler will start looking for the tsconfig.json file in the current directory and work its way up the parent directory. 2. Call TSC without any input files, and specify a directory containing the tsconfig.json file with the command-line argument --project (or -p). 3. If the input file is specified on the command line, the tsconfig.json file is ignored and compiled with the default optionCopy the code

Other confusing points

Interface and type declare the difference between types

There are two ways to define types: interfaces and Type aliases.

Interface can only define object types or functions.typeCan also define combination type, cross type (&, similar and set), joint type (|, similar to the intersection), the original type 2 and interface implementation and interface extends and implements, andtype aliasIs not. 3, interface can realize the combination of interfaces, buttype aliasIs not.Copy the code

Unknown to any

TypeScript 3.0 introduces the new unknown type, which is the safe counterpart of any.

Unknown: Before most operations can be performed on values of unknown type, some form of checking must be done. Any: No checks need to be performed before an operation is performed on a value of type any.Copy the code

For information about unknown, see juejin.cn/post/684490…

Const and readonly

Both define or modify values that cannot be changed and are read-only

Const: Used to define a constantreadonly: Modifies object propertiesCopy the code

The last

In my opinion, after learning a language and getting familiar with the concept of documents, we should finally deepen our experience in practice and explore more pits in order to better master it. After all, the purpose of learning is to better serve the work and business. Now TS is mature and everyone must be familiar with it. Later, there is time to summarize the problems encountered in their own development, thank you ~~~ on the article is not good, but also please include and point out, the first time to write in nuggets, manual face!

reference

www.typescriptlang.org/ www.tslang.cn/ ts.xcatliu.com/advanced/cl… www.softwhy.com/article-860… Blog. Poetries. Top / 2019/09/03 /… Kbscript.com/2017/01/27/… Juejin. Cn/post / 684490…