当前位置:网站首页>Typescript interface and the use of generics

Typescript interface and the use of generics

2022-07-06 07:22:00 wendyTan10

( One )TypeScript Interface

1. Declare an object type

//  By type (type) Alias declaration 
type InfoType = {
    name: string, age: number}

Interface interface, And you can define optional types (?), You can also define read-only properties (readonly )

interface IInfoType {
    
  readonly name: string
  age: number
  friend?: {
    
    name: string
  }
}
const info: IInfoType = {
    
  name: "why",
  age: 18,
  friend: {
    
    name: "kobe"
  }
}
console.log(info.friend?.name)
console.log(info.name)
info.age = 20

2. Index type

When our object key,value When I'm not sure , We can :

//  adopt interface To define the index type 
interface IndexLanguage {
    
  [index: number]: string
}

const frontLanguage: IndexLanguage = {
    
  0: "HTML",
  1: "CSS",
  2: "JavaScript",
  3: "Vue"
}
interface ILanguageYear {
    
  [name: string]: number
}
const languageYear: ILanguageYear = {
    
  "C": 1972,
  "Java": 1995,
  "JavaScript": 1996,
  "TypeScript": 2014
}

3. Type of function

The type of function can also be through interface Method definition of , But it is generally recommended to use type The way to define ;

// type CalcFn = (n1: number, n2: number) => number
//  Callable interfaces 
interface CalcFn {
    
  (n1: number, n2: number): number
}
function calc(num1: number, num2: number, calcFn: CalcFn) {
    
  return calcFn(num1, num2)
}
const add: CalcFn = (num1, num2) => {
    
  return num1 + num2
}
calc(20, 30, add)

4. Inheritance of interfaces

Interface interface Inheritance and class of class similar , All use keywords extends , And the interface can realize multiple inheritance ( Class does not support )

interface ISwim {
    
  swimming: () => void
}

interface IFly {
    
  flying: () => void
}
interface IAction extends ISwim, IFly {
    
}
const action: IAction = {
    
  swimming() {
    
  },
  flying() {
    
  }
}

5. Cross type

Following the use of joint types :

//  Joint type 
type WhyType = number | string
type Direction = "left" | "right" | "center"

Another type of method is called Cross type (Intersection Types):

type WType = number & string;

But there is no variable that satisfies number, Another string Value , Therefore, in the development process, we usually treat object type Cross over ;

// Cross type 
interface ISwim {
    
  swimming: () => void
}
interface IFly {
    
  flying: () => void
}
type MyType1 = ISwim | IFly
type MyType2 = ISwim & IFly
const obj1: MyType1 = {
    
  flying() {
    
  }
}
const obj2: MyType2 = {
    
  swimming() {
    
  },
  flying() {
    
  }
}

6. Interface implementation

interface ISwim {
    
  swimming: () => void
}
interface IEat {
    
  eating: () => void
}
//  Class implementation interface 
class Animal {
    
}
//  Inherit :  Only single inheritance can be implemented 
//  Realization :  Implementation interface ,  Class can implement multiple interfaces 
class Fish extends Animal implements ISwim, IEat {
    
  swimming() {
    
    console.log("Fish Swmming")
  }
  eating() {
    
    console.log("Fish Eating")
  }
}
class Person implements ISwim {
    
  swimming() {
    
    console.log("Person Swimming")
  }
}
//  Write some public API:  Interface oriented programming 
function swimAction(swimable: ISwim) {
    
  swimable.swimming()
}
// 1. Objects corresponding to all classes that implement the interface ,  All can be introduced into 
swimAction(new Fish())
swimAction(new Person())
swimAction({
    swimming: function() {
    }})

interface and type difference

We are often confused interface and type What is the difference between defining object types , How to choose ?

  • Define non object types , Generally recommended type, such as Direction、Alignment、 some Function;
  • Define object types , Then they are different :
    interface You can repeatedly define properties and methods for an interface ;
    type What is defined is an alias , Aliases cannot be repeated ;
     Insert picture description here

7. Assignment of literal quantity (freshness erase )

When assigning a variable identifier to another variable , Will be carried out in freshness Erase operation :

interface IPerson {
    
  name: string
  age: number
  height: number
}
function printInfo(person: IPerson) {
    
	console.log(person);
}
//  The code will directly report errors when compiling , non-existent address attribute 
printInfo({
    
  name: "why",
  age: 18,
  height: 1.88,
  address: " guangzhou ",
})

Type detection failed
 Please add a picture description
Here, only the values defined by yourself are used , Redundant values will be freshness Type detection after erasure , And through ts Type detection of ,

// ts The detection of will automatically push out a info Literal type of 
//  And have address Properties of , Assign it to printInfo() Will be address Erase ;
const info = {
    
  name: "wendy",
  age: 18,
  height: 1.88,
  address: " shenzhen "
}
//  What is assigned is the reference of the object , Will erase attributes 
printInfo(info); 
// {name:'wendy',age: 18, height: 1.88, address: ' shenzhen '}
//  And it can't be taken out address Value 

8. Enumeration type

Enumeration is to enumerate a set of possible values , List them one by one , Defined in a type , This type is the enumeration type ;
Use of enumeration types : Allow developers to define a set of named constants , Constants can be numbers number、 String type string; as follows :

// type Direction = "left" | "Right" | "Top" | "Bottom"
//  The type of enumeration is generally uppercase , Constant of string 
enum Direction {
    
  LEFT,
  RIGHT,
  TOP,
  BOTTOM
}
//  Enumeration is similar to a constant of a number , Equate to :
// enum Direction {
    
// LEFT = 0,
// RIGHT = 1,
// TOP = 2,
// BOTTOM =3
// }
function turnDirection(direction: Direction) {
    
  switch (direction) {
    
    case Direction.LEFT:
      console.log(" Change the direction of the character to the left ")
      break;
    case Direction.RIGHT:
      console.log(" Change the direction of the character to the right ")
      break;
    case Direction.TOP:
      console.log(" Change the direction of the character up ")
      break;
    case Direction.BOTTOM:
      console.log(" Change the direction of the character down ")
      break;
    default:
      const foo: never = direction;
      break;
  }
}
turnDirection(Direction.LEFT)
turnDirection(Direction.RIGHT)
turnDirection(Direction.TOP)
turnDirection(Direction.BOTTOM)

Enumeration types have values by default , For example, the above enumeration , The default value is :

enum Direction {
    
  LEFT = "LEFT",
  RIGHT = "RIGHT",
  TOP = "TOP",
  BOTTOM = "BOTTOM"
}

Of course , We can also enumerate other values , For example, this time will be from 100 Incrementing ;

enum Direction {
    
  LEFT = 100,
  RIGHT,
  TOP,
  BOTTOM
}

( Two )TypeScript The use of generics

The construction of code is not only standard and rigorous , You also want the code to be reusable , It's like we encapsulate some API when , Execute different events by passing in different parameters , But whether the type of parameter is ok A parameterized ; This is called Parameterization of type ;

1. Basic use of generics

Be similar to : Encapsulate a function , Pass in a parameter , And return this parameter ;

//  The type of data returned is consistent 
function fun(mes: string):string {
    
  return mes;
}

Although the above code implements the same return type , But it cannot be applied to other types , It is only fixed here as string The type of ;

// any The type of is about to lose type information , No difference from the first undefined 
function fun(mes: any):any {
    
  return mes;
}

We use special variables here - Type variable (type variable), It works on types , It's not worth it ;

//  When defining this function ,  I don't decide the type of these parameters 
//  Instead, let the caller tell... In the form of parameters , What type of function parameters should I have here 
function sum<Type>(num: Type): Type {
    
  return num
}

Here we can call it in two ways :

  • Mode one : adopt < type > Pass the type to the function ;
    //  Explicit incoming type 
    sum<number>(20)
    sum<{
            name: string}>({
          name: "why"})
    sum<any[]>(["abc"])
    
  • Mode two : Push to by type , Automatically push out the type of variable we passed in :
    //  Call mode 2 :  Type derivation 
    sum(50);
    sum("abc");
    

2. Generics can pass in multiple parameters

function foo<T, E, O>(arg1: T, arg2: E, arg3?: O, ...args: T[]) {
    
}
foo<number, string, boolean>(10, "abc", true)

And we are currently in normal development , Abbreviations are often used :

  • T: Type abbreviation ;
  • K,V: key and value Abbreviation , Key value pair ;
  • E: Element Abbreviation , Elements ;
  • O: Object Abbreviation , object ;

3. Generic interfaces use

interface IPerson<T> {
    
  id: T
  numList: T[],
  getID:( vallue: T) => void;
}

const p: IPerson<number> = {
    
  id: 1,
  numList: [99, 10, 10],
  getID: function(id: number) {
    
    console.log(id)
  }
}

4. Generic class usage

Define the use of a generic class :

class Point<T> {
    
  x: T
  y: T
  z: T
  constructor(x: T, y: T, z: T) {
    
    this.x = x
    this.y = y
    this.z = y
  }
}
const p1 = new Point("1.33.2", "2.22.3", "4.22.1")
const p2 = new Point<string>("1.33.2", "2.22.3", "4.22.1")
const p3: Point<string> = new Point("1.33.2", "2.22.3", "4.22.1")

5. Constraints of generics

We have a requirement that the incoming types have some commonalities , But commonalities are not in the same type :
For example, we want all the types to be passed in length Properties of , So this type may be string,array or Some objects ; Then if we require here, as long as we have length Properties of can be used as parameter types , How to operate this :

interface ILength {
    
  length: number
}
function getLength<T extends ILength>(arg: T) {
    
  return arg.length
}
getLength("abc")
getLength(["abc", "cba"])
getLength({
    length: 100})

( 3、 ... and )TypeScript Scope of action

TypeScript Support two ways to control our scope :

  • modularization : Each file can be a separate module , Support ES Module, Also support CommonJS;
    export function add(num1: number, num2: number) {
          
        return num1 + num2;
    }
    export function sub(num1: number, num2: number) {
          
        return num1 - num2;
    }
    
  • Namespace : adopt namespace To declare a namespace
    In the early days, it was called " Internal modules ", It mainly divides the internal scope of the module , Prevent some naming conflicts ;
    export namespace Time {
          
       export function format(time: string) {
          
            return '2022-07-05';
        }
    }
    //  The same method name is defined in different namespaces 
    export namespace Price {
          
        export function format(time: string) {
          
            return '20.22';
        }
    }
    //  Call after import 
    console.log(time.format("11111111"));
    console.log(price.format(123));
    

( Four ) Find and declare types

Types in projects , Almost all of them were written by ourselves , But there are also other types :

const imageEl = document.getElementById("image") as HTMLAnchorElement;

Will be very curious , there HTMLAnchorElement Where does the type come from ?
This involves typescript To the type of management and lookup The rules :
of typescript The file of : .d.ts file ; Used to declare types (declare), It is only used for type detection , inform typescript What types do we have ;
and typescript Where will we find our type declaration ?

  • Built in type declaration
  • Externally defined type declarations
  • Define your own type declaration

1. Built in type declaration

The built-in type declaration is typescript Self contained 、 Help us build JavaScript Some standardization of runtime API The statement of ; Include MathDate Etc , Also include DOMAPI(Window、Document);

const imageEl = document.getElementById("image") as HTMLAnchorElement;

Like here. getElementById Properties of , You can find ;
 Insert picture description here
Built in type declarations are usually installed when we typescript The environment will have ;

Click the project file to view lib dependent .d.ts file :https://github.com/microsoft/TypeScript/tree/main/lib

2. Externally defined type declarations

External type declarations are usually libraries that we use ( For example, import a third-party library ), You need to add additional type declarations to use ;
These libraries usually have two types of declarations :
Mode one : Type declarations built into your library ; The imported third-party library is in node_modules The file has its own (.d.ts file / Or you can add ); such as axios;
Mode two : Through the community public library DefinitelyTyped Store type declaration file
1. The GitHub Address :https://github.com/DefinitelyTyped/DefinitelyTyped/; There are a large number of compiled .d.ts Documents are available
2. The library looks for the address where the installation method is declared :https://www.typescriptlang.org/dt/search?search= ; This address is used to query the imported... Of the third-party package referenced in the project dt file , You can view additional instructions to import , Omit the purpose of browsing the installation package ; So let's say we type in react; install react Type declaration of : npm i @types/react --save-dev;
 Insert picture description here

3. Custom declaration

When there is no declared file in the third-party library , And when we want to declare some types for our code , You can customize the declaration file ; So how to customize the declaration file ? Create a... In the root directory of the project Any file name .d.ts file , And compile the types that need to be declared :

Declare variables / function / class

declare let whyName: string
declare let whyAge: number
declare let whyHeight: number
declare function whyFoo(): void
declare class Person {
    
  name: string
  age: number
  constructor(name: string, age: number)
}

We can also declare modules , such as lodash The module cannot be used by default , You can declare this module yourself :

Declaration module

Declare the syntax of the module : declare module ' Module name ' {}.
Inside the declaration module , We can go through export Export the corresponding library class function etc. ;

//  Declaration module  - lodash Is the name of the module 
declare module 'lodash' {
    
  export function join(arr: any[]): void
}

Declaration file :

Developing vue In the process of , The default is not to recognize us .vue Of documents , Then we need to make a file declaration ;
We used jpg This kind of picture file , Default typescript It's not supported either , It also needs to be declared ;

// .vue Statement of the file 
declare module '*.vue' {
    
    import {
     DefineComponent } from 'vue';
    const Component: DefineComponent<{
    }, {
    }, any>;
    export default Component;
} 
//  Declaration file 
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.png'
declare module '*.svg'
declare module '*.gif'

Declare a namespace

Let's say we have index.html It directly introduces jQuery
CDN Address : https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js
  "></script>

If in .ts Direct use in the file will result in an error in the operation :

TS2581: Cannot find name ‘$’. Do you need to install type definitions> for jQuery? Try npm i --save-dev @types/jquery.

There are two solutions :

  • Mode one : install @types/jquerynpm i --save-dev @types/jquery
  • Mode two : Is to add $ The namespace of :
//  Declare a namespace 
declare namespace $ {
    
  export function ajax(settings: any): any
}
原网站

版权声明
本文为[wendyTan10]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060718167910.html