directory

First, get started quickly

Second, VUE TS

Use vue-class-Component

Four, vue – property – the decorator

Is TypeScript inappropriate for VUE business development?

Property ‘name’ has no initializer

Vii. Comparison of downloads

Eight, tsconfig. Json

Nine, shims – vue. Which s

Ten, shims – TSX. Which s

Eleven, vuex – class

Twelve, ts

Decorator

Traffic lights

Property ‘$router’ does not exist on type ‘Login’

Use createDecorator to customize the decorator

TSLint removes semicolon and comma checks

React and TS

19. Transfer pictures to Base64

Twenty, the React + TS

External declarations and triple slash directives

TS+Webpack

Yarn Clear the cache and uninstall the global installation package

24. NPM download or YARN download to modify scaffolding

25. Countdown

Reference links:


 

 

 

First, get started quickly

TypeScript is a strongly typed version of JavaScript. Then, at compile time, the types and specific syntax are stripped away, producing pure JavaScript code.

TypeScript is a superset of JavaScript, which means it supports all JavaScript syntax.

The strength of strongly typed languages lies in static type checking.

TypeScript is a language developed by Microsoft.

Vue3.0 is developed using TS.

Github open source project: github.com/Microsoft/T…

Born in October 2012.

Vscode is written in ts: github.com/Microsoft/v…

Packing:

yarn global add typescript
Copy the code

Check version:

 tsc -V
Copy the code

Initialization:

tsc --init
Copy the code

 

index.ts:

function greeter(person) {
  return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);
Copy the code

Programming into js files:

tsc index.ts
Copy the code

index.js:

function greeter(person) {
    return "Hello, " + person;
}
var user = "Jane User";
document.body.innerHTML = greeter(user);
Copy the code

Type check:

If the function argument declaration is a string but a number is passed, a warning message is displayed

function greeter(person:string) {
  return "Hello, " + person;
}

let user = 1;

document.body.innerHTML = greeter(user);
Copy the code

Error if no parameter is passed:

Interface interface:

Define the fields that Person contains

interface Person {
  firstName: string;
  lastName: string;
}

function greeter(person: Person) {
  return "Hello, " + person.firstName + "" + person.lastName;
}

let user = { firstName: "Jane".lastName: "User" };

document.body.innerHTML = greeter(user);
Copy the code

Create a class with class:

class Student {
    fullName: string;
    constructor(public firstName, public middleInitial, public lastName) {
        this.fullName = firstName + "" + middleInitial + "" + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstName + "" + person.lastName;
}

let user = new Student("Jane"."M."."User");

document.body.innerHTML = greeter(user);
Copy the code

After compilation:

var Student = / * *@class * / (function () {
    function Student(firstName, middleInitial, lastName) {
        this.firstName = firstName;
        this.middleInitial = middleInitial;
        this.lastName = lastName;
        this.fullName = firstName + "" + middleInitial + "" + lastName;
    }
    returnStudent; } ());function greeter(person) {
    return "Hello, " + person.firstName + "" + person.lastName;
}
var user = new Student("Jane"."M."."User");
document.body.innerHTML = greeter(user);
Copy the code

Visit the web page, index.html:

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
</head>
<body>
  <script src="./index.js"></script>
</body>
</html>
Copy the code

Effect:

Automatic completion function:

Second, VUE TS

The. Vue suffix must be added when importing the Vue file, otherwise the editor will not recognize it

TS routing:

import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'
import Home from '.. /views/Home.vue'

Vue.use(VueRouter)

  const routes: Array<RouteConfig> = [
  {
    path: '/'.name: 'Home'.component: Home
  },
  {
    path: '/about'.name: 'About'.// route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () = > import(/* webpackChunkName: "about" */ '.. /views/About.vue')}]const router = new VueRouter({
  mode: 'history'.base: process.env.BASE_URL,
  routes
})

export default router
Copy the code
import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'

Vue.use(VueRouter)

  const routes: Array<RouteConfig> = [
  {
    path: '/'.redirect: '/login'
  },
  {
    path: '/login'.component: () = > import('.. /views/Login.vue')}]const router = new VueRouter({
  mode: 'history'.base: process.env.BASE_URL,
  routes
})

export default router
Copy the code

Use vue-class-Component

class-component.vuejs.org/

Github.com/vuejs/vue-c…

Annotating: annotation

Add, add, subtract, subtract:

<template>
  <div>
    <div>{{count}}</div>
    <button @click="handleSub">Reduction of</button>
    <button @click="handleAdd">add</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class Login extends Vue {
  count = 0

  handleSub() {
    this.count--
  }
  
  handleAdd() {
    this.count++
  }
}

export default Login
</script>
Copy the code

Or:

<template>
  <div>
    <div>{{count}}</div>
    <button @click="handleSub">Reduction of</button>
    <button @click="handleAdd">add</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class Login extends Vue {
  data() {
    return {
      count: 0}}handleSub() {
    this.count--
  }
  
  handleAdd() {
    this.count++
  }
}

export default Login
</script>
Copy the code

 

V – model:

<template>
  <div>
    <input v-model="username">
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class Login extends Vue {
  username = 'admin'
}

export default Login
</script>
Copy the code

Mount life cycle:

<template>
  <div>
    1
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class Login extends Vue {
  mounted () {
    console.log('Mount done')}}export default Login
</script>
Copy the code

Calculated attributes:

<template>
  <div>
    {{double}}
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class Login extends Vue {
  count = 1
  get double() {
    return this.count * 2}}export default Login
</script>
Copy the code

Parent/child component transmission:

The parent component

<template>
  <div>
    <Icon :name="visible ? 'xianshimima' : 'buxianshimima'" @onClick="handleVisible"></Icon>
  </div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'
import Icon from '.. /components/Icon'

@Component({
  components: {
    Icon
  }
})
class Login extends Vue {
  visible = false
  
  handleVisible() {
    this.visible = !this.visible
  }
}

export default Login
</script>
Copy the code

Child components

<template>
  <span :class="[`icon iconfont icon-${name}`]" @click="handleClick"></span>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'

@Component
class Icon extends Vue {
  @Prop()
  name: string

  handleClick() {
    this.$emit('onClick')}}export default Icon
</script>
Copy the code

Child components can also be written this way

<template>
  <span :class="[`icon iconfont icon-${name}`]" @click="handleClick"></span>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'

const IconProps = Vue.extend({
  props: {
   name: String 
  }
})

@Component
class Icon extends IconProps {
  handleClick() {
    this.$emit('onClick')}}export default Icon
</script>
Copy the code

Add routing hook:

vue-class-component.ts

import Component from 'vue-class-component'

Component.registerHooks([
  "beforeRouteEnter"
])
Copy the code

Import this file in the import file main.ts

Available in components

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Test2 extends Vue {
  beforeRouteEnter(to, from, next) {
    console.log(1)
    next()
  }
}
</script>
Copy the code

 

 

Four, vue – property – the decorator

www.npmjs.com/package/vue…

Vue property decorator

Parent and child components pass values and parameters

The parent component:

<template>
  <div>
    <Icon :name="visible ? 'show' : 'hide'" @onClick="handleVisible"></Icon>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import Icon from '.. /components/Icon.vue'

@Component({
  components: {
    Icon
  }
})
class Login extends Vue {
  visible = false
  
  handleVisible(payload:object) {
    this.visible = !this.visible
  }
}

export default Login
</script>
Copy the code

Child components:

<template>
  <span :class="[`icon iconfont icon-${name} ${className}`]" @click="handleClick"></span>
</template>

<script lang="ts">
import { Vue, Component, Prop, Emit } from 'vue-property-decorator'

@Component
class Icon extends Vue {
  @Prop({ default: 'zhanwei'}) name! : string @Prop({default: ' '}) className! : string @Emit('onClick')
  handleClick() {
    return { id: 2}}}export default Icon
</script>
Copy the code

Is TypeScript inappropriate for VUE business development?

www.zhihu.com/question/31…

 

Property ‘name’ has no initializer

Property ‘name’ has no initializer and is not definitely assigned in the constructor.

Solution 1:

Change the strict field in the tsconfig.json file to false

Solution 2:

The attribute name is followed by an exclamation mark, which is a modifier and the identity is ignored

<template>
  <span :class="[`icon iconfont icon-${name}`]" @click="handleClick"></span>
</template>

<script lang="ts">
import { Vue, Component, Prop, Emit } from 'vue-property-decorator'

@Component
class Icon extends Vue {
  @Prop({ default: 'zhanwei'}) name! : string @Emit('onClick')
  handleClick() {
    return { id: 2}}}export default Icon
</script>
Copy the code

Vii. Comparison of downloads

 

Eight, tsconfig. Json

Ts of configuration

{
  "compilerOptions": {
    "target": "esnext".// Target version for compilation
    "module": "esnext".// Specify which module system code to generate
    "strict": true.Static type checking
    "jsx": "preserve".//
    "importHelpers": true."moduleResolution": "node"."experimentalDecorators": true."esModuleInterop": true."allowSyntheticDefaultImports": true."sourceMap": true.// Whether to generate a map file
    "baseUrl": "."."types": [
      "webpack-env"]."paths": {
      "@ / *": [
        "src/*"]},"lib": [
      "esnext"."dom"."dom.iterable"."scripthost"]},"include": [
    "src/**/*.ts"."src/**/*.tsx"."src/**/*.vue"."tests/**/*.ts"."tests/**/*.tsx"]."exclude": [
    "node_modules"]}Copy the code

 

Nine, shims – vue. Which s

Shims: gasket

Since TypeScript does not support *. Vue files by default, you need to create a shims-vue.d.ts file in a directory that your project should use, such as SRC /shims-vue.d.ts. Files used to support the *. Vue suffix;

Vue files are used by TypeScript to recognize. Vue files. By default, Ts does not support importing vue files

 

declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}
Copy the code

Ten, shims – TSX. Which s

Allows you to write JSX code in Vue projects with.tsx ending files

import Vue, { VNode } from 'vue'

declare global {
  namespace JSX {
    // tslint:disable no-empty-interface
    interface Element extends VNode {}
    // tslint:disable no-empty-interface
    interface ElementClass extendsVue {} interface IntrinsicElements { [elem: string]: any; }}}Copy the code

Eleven, vuex – class

www.npmjs.com/package/vue…

Use the warehouse for addition and subtraction

Warehouse:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

interface Payload {
  key: string,
  value: any
}

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    setState(state:any, payload:Payload) {
      state[payload.key] = payload.value
    }
  },
  actions: {},modules: {}})Copy the code

Page:

<template>
  <div>
    <div>{{count}}</div>
    <button @click="handleSub">Reduction of</button>
    <button @click="handleAdd">add</button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import { State, Mutation } from 'vuex-class'

@Component
class Login extends Vue {
  @State('count') count! :number @Mutation('setState') setState! :Function

  handleSub() {
    let count = this.count - 1
    this.setState({ key: 'count'.value: count })
  }

  handleAdd() {
    let count = this.count + 1
    this.setState({ key: 'count'.value: count })
  }
}

export default Login
</script>
Copy the code

 

Twelve, ts

Initialization:

Open terminal in an empty folder -> type TSC –init to automatically generate tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    // "incremental": true, /* Enable incremental compilation */
    "target": "es5"./* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs"./* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    // "lib": [], /* Specify library files to be included in the compilation. */
    "allowJs": true./* Allow javascript files to be compiled. */
    // "checkJs": true, /* Report errors in .js files. */
    // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true, /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
    // "sourceMap": true, /* Generates corresponding '.map' file. */
    // "outFile": "./", /* Concatenate and emit output to single file. */
    "outDir": "./js"./* Redirect output structure to the directory. */
    // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true, /* Enable project compilation */
    // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
    // "removeComments": true, /* Do not emit comments to output. */
    // "noEmit": true, /* Do not emit outputs. */
    // "importHelpers": true, /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true./* Enable all strict type-checking options. */
    // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true, /* Enable strict null checks. */
    // "strictFunctionTypes": true, /* Enable strict checking of function types. */
    // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true, /* Report errors on unused locals. */
    // "noUnusedParameters": true, /* Report errors on unused parameters. */
    // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
    // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [], /* List of folders to include type definitions from. */
    // "types": [], /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true./* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */

    /* Source Map Options */
    // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    "experimentalDecorators": true.// Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */}}Copy the code

Monitor ts file changes, automatic compilation:

Vscode -> Terminal -> Run Tasks -> typescript -> TSC: Monitor – (tsconfig.json directory)

 

Lesson 1:

function test(name:string) {
  console.log(name)
}

test('hello3')

/ / yuan group
let tuple:[string, number, string] = ['a'.1.'b']
console.log(tuple)

/ / arbitrary value
let person:any = 'xu'
console.log(person)

// Four elements: call, argument, return value, action
function fun(name:string) :string {
  console.log(name)
  return name
}

fun('xu')

//never is unreachable
const error = ():never= > {
  throw new Error('wrong')}//error()


const loop = () = > {
  while(true);
}
//loop()

console.log(1)


/ / the enumeration
enum Color { Red = 2, Green, Blue }

console.log(Color.Red)  / / 2

enum obj {
  None,
  Read,
  G = '123'.length
}

console.log(obj)

enum Enum {
  A
}

let a = Enum.A
console.log(a)  / / 0

let na = Enum[a]
console.log(na)  //A
Copy the code

Lesson 2:

function sayHello(person: string) {
  return 'Hello,' + person
}

let user:string = 'a'
console.log(sayHello(user))

let num:number = 1

// If the declared type is not displayed, type inference is performed
let a = 'a'
a = 'b'  // Assign other types, an error is reported

let flag:boolean = true

// Array of numeric types
let arr:number[] = [1.2]
let strArr:string[] = ['a'.'b']
let objArr:object[] = [{}]

// Generic
let arr1:Array<number> = [1]
let strArr1:Array<string> = ['a'.'b']

/ / yuan group
let arr2:[number, string, boolean] = [1.'2'.true]

//null, undefined
let my_null:null = null
let my_undefined:undefined = undefined

// It can be a string or undefined
let c:string | undefined
console.log(c)

//never a value that never occurs
// let my_never: never = (() => {
// throw new Error()
/ /}) ()

//any Any type
let my_any:any = 'Any type'
console.log(my_any)

// Any type of array
let arrAny:any[] = ['a'.1.true]

function run() :void {
  console.log('run')
}

run()

function getName() :string {
  return 'xu'
}

console.log(getName())

const myRun = ():void= > {
  console.log('myRun')
}

myRun()

const myGetName = ():string= > {
  return 'myGetName'
}

console.log(myGetName())

The constructor Boolean does not create a Boolean value
//let myBoolean:boolean = new Boolean(1)
Copy the code

Lesson 3:

/ / function
// No return value is void
function getInfo(name:string, age:number) :string {
  return I call `${name}This year,${age}Years old. `
}

console.log(getInfo('xu'.30))

let getInfo1 = (name:string, age:number):string= > {
  return I call `${name}This year,${age}Years old. `
}

console.log(getInfo('xu'.31))

// Full type
let getInfo2:(name:string, age:number) = > string = (name:string, age:number):string= > {
  return I call `${name}This year,${age}Years old. `
}

let getInfo3:Function = (name:string, age:number):string= > {
  return I call `${name}This year,${age}Years old. `
}

// Function optional argument, add a hello
function myInfo(name: string, age? : number) :string {
  if (typeof age === 'number') {
    return I call `${name}This year,${age}Years old. `
  } else {
    return I call `${name}`}}console.log(myInfo('xu'))

/ / the default value
function myInfo1(name: string, age:number = 32) :string {
  if (typeof age === 'number') {
    return I call `${name}This year,${age}Years old. `
  } else {
    return I add `${name}`}}console.log(myInfo1('xu'))

/ / sum
function sum(a:number, b:number) :number {
  return a + b
}

console.log(sum(1.2))

// Remaining parameters
function sum1(. rest:number[]) :number {
  console.log(rest) / / array
  return rest.reduce((prev, item) = > {
    return prev + item
  }, 0)}console.log(sum1(1.2.3.4.5))

// Enumeration type
// 0: female, 1: male, 2: confidential

enum Sex {
  gril,
  boy,
  secret
}

let xu:Sex = Sex.boy
console.log(xu)
let xu1:Sex = 3
console.log(xu1)

function getSex(sex:Sex) :string {
  if (sex === Sex.gril) {
    return 'I'm a girl'
  } else if (sex === Sex.boy) {
    return 'I'm a boy'
  } else {
    return 'secret'}}console.log(getSex(xu))


class A {
  v:number = 100
  test(num:number) {
    if (num > this.v) {
      console.log('big');
    } else if (num < this.v) {
        console.log('small')}else {
        console.log('for the')}}}let a = new A()

a.test(100)

let isDone:boolean = false

let isDone1:object = new Boolean(1)

let isDone2:Boolean = new Boolean(1)

let isDone3:boolean = Boolean(1)

// A variable can be identified as an arbitrary value type if its type is not specified when it is declared
let something   //let something:any
something = 1
something = 'a'

// Union type
let myA: string | number
myA = 'a'
myA = 1


function getLength(something: string | []) :number {
  return something.length
}

let myB: string | number
myB = 'A'
myB.length
myB = 1
/ / myB. Length / / an error

let arr:number[] = [1.3.2]
arr.sort((a, b) = > {
  return a - b
})


console.log(arr)

function is(ar:string,sr:string) :boolean {
  let result = true
  if(ar.length===sr.length){
      for(let i=0; i<ar.length; i++){if(ar.indexOf(sr[i])===-1){
             result = false
          }
      }
     result = true
  } else {
    result = false
  }
  return result
}
console.log(is("asa"."aas"))function isAng(arr:string,trr:string) :boolean{
  if(arr.length===trr.length){
      for(var i=0; i<arr.length; i++){if(arr.indexOf(trr[i])===-1) {return false}}return true
  }
  return false
}

console.log(isAng('listen'.'silenta'))
Copy the code

Lesson 4:


// Function overload
function add(a:string, b:string) :string;
function add(a:number, b:number) :number;

function add(a:any, b:any) :any {
  if (typeof a === 'string') {
    return a + The '-' + b
  } else {
    return a + b
  }
}

console.log(add('a'.'b'))

/ / class
// the pubulic protected private modifier
// Static attribute static
class Person {
  public name: string
  protected age: number

  static height: number = 170

  constructor(name:string, age:number) {
    this.name = name
    this.age = age
    console.log(Person.height, Person.getHeight())
  }

  protected getName():string {
    return 'My name isThe ${this.name}`
  }

  static getHeight():number {
    return this.height
  }
}

let xu = new Person('xu'.30)
//console.log(xu.getName())
console.log(Person.getHeight())

// class Animal {
// name:string
// constructor(name:string) {
// this.name = name
/ /}
// sayHi() {
// return `My name is ${this.name}`
/ /}
// }

// let a = new Animal('jack')
// console.log(a.sayHi())

/ / inheritance
class Programmer extends Person {
  job:string
  constructor(name:string, age:number, job:string) {
    super(name, age)
    this.job = job
    console.log(this.age)
  }
  getJob() {
    return `The ${this.getName()}Age,The ${this.age}My job isThe ${this.job}`}}let xu1 = new Programmer('Xu Tongbao'.30.'the web front end')
//console.log(xu1.getName())
console.log(xu1.getJob())
//console.log(xu1.age)

/ / abstract classes
abstract class Animal {
  name: string
  constructor(name: string) {
    this.name = name
  }
  getName():string {
    return this.name
  }
  abstract eat():void
}

class Cat extends Animal {
  food: string
  constructor(name: string, food: string) {
    super(name)
    this.food = food
  }
  eat():void {
    console.log(`The ${this.getName()}Love to eat fish `)}}let ketty = new Cat('the cat'.'fish')
ketty.eat()

// For a more concise way, there is no need to define name and no need to assign
class MyAnimal {
  constructor(public name:string){}getName() {
    return this.name
  }
}

let myAnimal = new MyAnimal('the cat')
console.log(myAnimal.getName())

/ / interface
interface Goods {
  name: string
  price: number
  flag: boolean
}

let cartList: Goods[] = [
  {
    name: 'apple'.price: 8.flag: true
  },
  {
    name: 'banana'.price: 5.flag: false}]function goodsInfo(goods:Goods) {
  console.log(`${goods.name}now${goods.price}Yuan a kilo${goods.flag ? ', on sale ' : ' '}`)
}

cartList.forEach(item= > {
  goodsInfo(item)
})

// Function interface
interface GoodsInfo {
  (goods: Goods): string
}

let myGoodsInfo: GoodsInfo = (goods:Goods):string= > {
  return `${goods.name}now${goods.price}Yuan a kilo${goods.flag ? ', on sale ' : ' '}`
}

// implements an interface using implements
interface PersonI {
  name: string,
  age: number,
  getName():string
}

interface WebI {
  name: string,
  age: number,
  job: string
  getName(): string
  getJob(): string
}

// Interfaces can also be inherited
interface WebIPlus extends PersonI {
  job: string,
  getJob(): string
}


class MyPerson implements PersonI {
  name: string
  age: number

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

  getName() {
    return this.name
  }
}

class Web extends MyPerson implements WebIPlus {
  job: string
  constructor(name: string, age: number, job: string) {
    super(name, age)
    this.job = job
  }

  getJob() {
    return this.job
  }

  getInfo() {
    return `The ${this.name}.The ${this.age}.The ${this.job}`}}let xu2 = new Web('xu'.30.'web')
console.log(xu2.getInfo())
Copy the code

Lesson 5:

let arr:Array<string> = ['a'.'b'.'c']

// Generic functions
function getMin<T> (arr:T[]) :T {
  let min:T = arr[0]
  arr.forEach(val= > {
    if (val < min) {
      min = val
    }
  })
  return min
}

let min = getMin<number>([5.2.8.4.4])
console.log(min)

let min1 = getMin<string>(['d'.'s'.'c'.'e'.'f'])
console.log(min1)

/ / a generic class
class Min<T> {
  list: T[] = []
  add(params: T):void {
    this.list.push(params)
  }
  getMin(): T {
    let min:T = this.list[0]
    this.list.forEach(val= > {
      if (val < min) {
        min = val
      }
    })
    return min
  }
}

// Function interface generics
interface Min<T> {
  (arr: T[]): T
}


/ / a decorator
function logClass(target:any) {
  console.log('I'm a decorator', target)
  target.prototype.name = 'I'm the name that the decorator added'
  target.prototype.getName = function () {
    console.log('I am the way decorator is added')}}function logName(params:any) {
  console.log(params)
  return function(target:any, attr:any) {
    console.log('Property decorator', target)  / / instance
    console.log('attr', attr)  // Use the decorator properties
    target[attr] = params
  }
}

// function logName(target:any, attr:any) {
// console.log(' property decorator ', target) // instance
// console.log('attr', attr) // Uses decorator attributes
// target[attr] = 'xu'
// }

@logClass
class Person {
  @logName('I'm the Person class')
  myName: string | undefined

  @logName(40)
  age:number | undefined

  getInfo() {
    console.log(this.myName, this.age)
  }
}

let a = new Person()
console.log(a)
a.getInfo()
Copy the code

 

Notes:

In TypeScript, use: to specify the type of a variable, with or without Spaces before and after:.

TypeScript only checks statically, and if errors are found, an error is reported at compile time.

The constructor Boolean creates objects that are not Booleans.

When the constructor is modified to private, the class is not allowed to be inherited or instantiated.

When the constructor is protected, the class is only allowed to be inherited, not instantiated.

A read-only property keyword that is allowed only in a property declaration or index signature or constructor.

A class can only inherit from another class, but can implement multiple interfaces.

A variable is recognized as any value type if its type is not specified when it is declared.

Joint type using | separated for each type.

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.

Decorator

The proposal’s official website: github.com/tc39/propos…

Tc39. Es/proposal – DE…

A decorator is a function that handles a class. The first argument to the decorator function is the target class to decorate.

@decorator
class A {}

/ / is equivalent to

class A {}
A = decorator(A) || A;
Copy the code

If one argument is not enough, you can wrap another function around the decorator.

function testable(isTestable) {
  return function(target) { target.isTestable = isTestable; }}Copy the code

Mixins instances:

// The list is merged into the prototype chain
const mixins = (. list:any) = > (target:any) = > {
  Object.assign(target.prototype, ... list) }// The object to merge
const Foo = {
  name: 'xu'.foo() {
    console.log('foo')},bar() {
    console.log('bar')}}// Use decorators
@mixins(Foo)
class MyClass {}/ / test
let obj = new MyClass();
(obj as any).foo();
(obj as any).bar();
console.log((obj as any).name)
Copy the code

Decorators serve as annotations.

Decorators cannot be used for functions because of function promotion.

Log instance:

// Calculator class
class Computed {
  name:string
  constructor(name:string) {
    this.name = name
  }
  @log
  add(a:number, b:number) {
    console.log(this.name)
    return a + b
  }

  @log
  sub(a:number, b:number) {
    return a - b
  }
}

// Log decorator
function log(target:any, name:any, descriptor:any) {
  let oldValue = descriptor.value
  descriptor.value = function () {
    / / log
    console.log('Log: call${name}, the parameter isThe ${Array.from(arguments)}`)
    //return oldValue.call(this, ... Arguments) // Execute the old method
    return oldValue.apply(this.arguments)}return descriptor
}

/ / test
const computed = new Computed('xu')
console.log(computed.add(2.4))
console.log(computed.sub(4.2))
Copy the code

Traffic lights

class Light {
  constructor() {
    this.init()
  }
  init() {
    return this.light(3.'green light')
      .then(() = > {
        return this.light(2.'red light')
      })
      .then(() = > {
        return this.light(1.'yellow')
      }).then(() = > {
        this.init()
      }).catch(() = > {
        console.log('Failed')})}light(time: number, type: string) {
    return new Promise((resolve, reject) = > {
      let timer = setInterval(() = > {
        console.log(type, time)
        time--
        if (time === 0) {
          clearInterval(timer)
          resolve()
          //reject()}},1000)}}}let ligth = new Light()
Copy the code

 

interface LampI {
  loop: number
  start(): void
}

/ / the traffic lights
class Lamp<T> {
  loop: number
  constructor(public green: number, public red: number, public yellow: number) {
    this.loop = 0
  }
  start() {
    let loopFun = async() = > {await new Promise((resolve) = > {
        setTimeout(() = > {
          this.loop++
          this.print()
          loopFun()
        }, 1000)
      })
    }
    loopFun()
  }
  test(a:T) {
    console.log(a)
  }
  private print(): void {
    if (this.loop <= this.green) {
      console.log(` green lightThe ${this.green + 1 - this.loop}`)}else if (this.loop <= this.green + this.red) {
      console.log(` red lightThe ${this.green + this.red + 1 - this.loop}`)}else if (this.loop <= this.green + this.red + this.yellow) {
      console.log(` yellow lightThe ${this.green + this.red + this.yellow + 1 - this.loop}`)}else {
      this.loop = 1
      console.log(` green lightThe ${this.green}`)}}}let lamp = new Lamp(3.2.1)
lamp.start()
lamp.test([1.2.3])
lamp.test('hello')
Copy the code

 

Property ‘$router’ does not exist on type ‘Login’

Solutions:

(1) Import routing packages from components that use routing:

import VueRouter from 'vue-router';
Copy the code

(2) Declare this as any

(this as any).$router.push('/index')
Copy the code

(3) Define the $router attribute in the class

export default class Login extends Vue {
  $router
}
Copy the code

Use createDecorator to customize the decorator

decorators.ts:

import { createDecorator } from 'vue-class-component'

export const Log = createDecorator((options:any, key:string) = > {
  // Backup the original method
  const originalMethod = options.methods[key]

  // Add log logic
  options.methods[key] = function wrapperMethod(. args:any) {
    // Prints logs
    console.log(` logs:${key}(`. args,') ')

    // Execute the original method
    originalMethod.apply(this, args)
  }
})


export const LogPlus = (payload: string) = > createDecorator((options:any, key:string) = > {
  // Backup the original method
  const originalMethod = options.methods[key]

  // Add log logic
  options.methods[key] = function wrapperMethod(. args:any) {
    // Prints logs
    console.log(`${payload}Log:${key}(`. args,') ')

    // Execute the original method
    originalMethod.apply(this, args)
  }
})
Copy the code

Use:

<template>
  <div>
    <div>{{msg}}</div>
    <div>{{count}}</div>
    <button @click="handleSub(1)">Reduction of</button>
    <button @click="handleAdd(1)">add</button>
    <TestComponent name="hello"></TestComponent>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { Log, LogPlus } from '.. /utils/decorators'
import TestComponent from '.. /components/TestComponent.vue'

@Component({
  components: {
    TestComponent
  }
})
export default class Test extends Vue {
  msg = 'hello'
  count = 0

  @Log
  handleAdd(step:number) {
    this.count += step
  }

  @LogPlus('subtraction')
  handleSub(step:number) {
    this.count -= step
  }
}
</script>
Copy the code

 

TSLint removes semicolon and comma checks

    "trailing-comma": [false]."semicolon": [false].Copy the code

React and TS

Scaffolding:

npx create-react-app react-ts-app --typescript
Copy the code

According to the package used:

yarn add react-router-dom redux react-redux redux-thunk redux-logger axios
Copy the code

Statement for installing TS version:

yarn add @types/react-router-dom @type/react-redux
Copy the code

19. Transfer pictures to Base64

  const getBase64Image = (url: string) = > {
    return new Promise((resolve,reject) = > {
      let image = new Image();
      / / CORS strategy, problems will cross domain https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
      image.setAttribute("crossOrigin".'Anonymous');
      image.src = url;
      image.onload = () = > {
        let canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        (canvas as any).getContext('2d').drawImage(image,0.0);
        let result = canvas.toDataURL('image/png');
        resolve(result);
      }
      image.onerror = () = > {
        reject('Picture flow exception'); }; })}Copy the code

 

Twenty, the React + TS

Controlled components:

  handleInput(e: ChangeEvent<HTMLInputElement>, field: string) {
    // @ts-ignore
    this.setState({
      [field]: e.target.value
    })
  }
Copy the code

HTMLInputElement:

KeyUp event:

  handleEnter(e: KeyboardEvent<HTMLInputElement>) {
    if(e.keyCode === 13) {
      this.handleLogin()
    }
  }
Copy the code

Click events:

  handleVisible(e: MouseEvent<Element>, count: number) {
    let { visible } = this.state
    this.setState({
      visible: !visible
    })
  }
Copy the code

Ignore type checking:

// @ts-ignore
Copy the code

Rolling events:

  const handleScroll = (e: React.UIEvent<HTMLDivElement, globalThis.UIEvent>) = > {
    let scrollTop = (e.target as Element).scrollTop
    console.log(scrollTop)
  }
Copy the code

WithRouter:

Redux data reads and writes:

import React, { Dispatch } from 'react'
import { connect } from 'react-redux'
import { IState } from '.. /interface'

interface IProps {
  list: any[],
  currentId: number,
  onSetState: (key: string, value: any) = > void
  onDispatch: (action: Function) = > void
}


const Sidebar = (props: IProps) = > {
  const { list, currentId } = props

  const handleNav = (id: number) = > {
    props.onSetState('currentId', id);
    //@ts-ignore
    document.getElementById(id + ' ').scrollIntoView({ block: 'start'.behavior: 'smooth'})}const sidebarDom = list.map((item: any) = > (
    <div key={item.id} className={`m-sidebar-itemThe ${currentId= = =item.id ? 'active' :"'} `}onClick={()= > handleNav(item.id) }>{item.title}</div>
  ))

  return (
    <div className="m-sidebar">
      {sidebarDom}
    </div>)}const mapStateToProps = (state: IState) = > {
  return {
    list: state.book.list,
    currentId: state.book.currentId
  }
}

const mapDispatchToProps = (dispatch: Dispatch<any>) = > {
  return {
    onSetState(key: string, value: any) {
      dispatch({ type: 'SET_STATE', key, value })
    },
    onDispatch(action: Function) {
      dispatch(action)
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar)
Copy the code

Reducer:

import { IBookState, IAction } from '.. /.. /interface'

const defaultState: IBookState = {
  title: 'Millet Book City'.currentId: 0.isRealScroll: true.list: [].myBooks: []}const reducer = (state = defaultState, action: IAction) = > {
  switch (action.type) {
    case 'SET_STATE':
      let newState = JSON.parse(JSON.stringify(state))
      newState[action.key] = action.value
      return newState
    default:
      return state
  }
}

export default reducer
Copy the code

actionCreator.js:

import { Dispatch } from 'react'
import Api from '.. /.. /api'

const list = () = > (dispatch: Dispatch<any>) = > {
  Api.list().then(res= > {
    if (res.code === 200) {
      dispatch({ type: 'SET_STATE'.key: 'list'.value: res.data })
    }
  })
}

export default {
  list
}
Copy the code

Interface:

export interface IBookState {
  title: string,
  currentId: number,
  isRealScroll: boolean,
  list: any[],
  myBooks: any[]
}

export interface IState {
  book: IBookState
}

export interface IAction {
  type: string,
  key: string,
  value: any
}
Copy the code

Login page hook writing:

import React, { useState, MouseEvent, KeyboardEvent } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import Icon from '.. /components/Icon'
import Api from '.. /api'

const Login = (props: RouteComponentProps) = > {
  const [ username, setUsername ] = useState('admin')
  const [ password, setPassword ] = useState('123456')
  const [ visible, setVisible ] = useState(false)

  const handleVisible = (e: MouseEvent, count: number ) = >{ setVisible(! visible) }const handleEnter = (e: KeyboardEvent<HTMLInputElement>) = > {
    if (e.keyCode === 13 ) {
      handleLogin()
    }
  }

  const handleLogin = () = > {
    Api.login({ username, password }).then(res= > {
      if (res.code === 200) {
        localStorage.setItem('token', res.data.username)
        props.history.push('/index/home')}}}return (
    <div>
      <div>
        <input value={username} onChange={(e)= >SetUsername (e.target.value)} placeholder= placeholder;</input>
      </div>
      <div>
        <input value={password} onChange={(e)= >SetPassword (e.target.value)} onKeyUp={(e) => handleEnter(e)} placeholder=" Please input password "type={visible? 'text' : 'password' }></input>
        <Icon name={ visible ? 'show' : 'hide'}onClick={ (e.count) = > handleVisible(e, count) } className="m-login-icon"></Icon>
      </div>
      <button onClick={()= >HandleLogin ()} > to log in</button>
    </div>)}export default Login
Copy the code

Login page class:

import React, { Component, ChangeEvent, KeyboardEvent, MouseEvent } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import Icon from '.. /components/Icon'
import Api from '.. /api'

interface IState {
  username: string,
  password: string,
  visible: boolean
}

interface IProp extends RouteComponentProps {

}

export default class LoginClass extends Component<IProp.IState> {
  constructor(props: IProp) {
    super(props)
    this.state = {
      username: 'admin'.password: '123456'.visible: false}}handleInput(e: ChangeEvent<HTMLInputElement>, field: string) {
    // @ts-ignore
    this.setState({
      [field]: e.target.value
    })
  }

  handleVisible(e: MouseEvent<Element>, count: number) {
    let { visible } = this.state
    this.setState({
      visible: !visible
    })
  }

  handleEnter(e: KeyboardEvent<HTMLInputElement>) {
    if(e.keyCode === 13) {
      this.handleLogin()
    }
  }

  handleLogin() {
    let { username, password } = this.state
    Api.login({ username, password }).then(res= > {
      if (res.code === 200) {
        localStorage.setItem('token', res.data.username)
        this.props.history.push('/index/home')}}}render() {
    let { username, password, visible } = this.state
    return (
      <div>
        <div>
          <input value={username} onChange={(e)= >This.handleinput (e, 'username')} placeholder="</div>
        <div>
          <input value={password} onChange={(e)= >This.handleinput (e, 'password')} onKeyUp={(e) => this.handleEnter(e)} placeholder=" please input password "type={visible? 'text' : 'password' }/><Icon name={ visible ? 'show' : 'hide'}onClick={ (e.count) = > this.handleVisible(e, count) } className="m-login-icon"></Icon>
        </div>
        <button onClick={()= >Enclosing handleLogin ()} > to log in</button>
      </div>)}}Copy the code

Icon component hook

import React, { MouseEvent } from 'react'

interface IProps {
  name: string, className? : string, onClick? :(e: MouseEvent, count: number) = > void
}

const Icon = (props: IProps) = > {
  let { name, className = ' ', onClick = () = > {} } = props
  return (
    <span className={`icon iconfont icon-The ${name} ${className} `}onClick={(e)= > onClick(e, 1)}></span>)}export default Icon
Copy the code

Icon component Class

import React, { Component, MouseEvent } from 'react'

interface IProps {
  name: string, className? : string, onClick? :(e: MouseEvent, count: number) = > void
}


export default class IconClass extends Component<IProps> {
  render() {
    const { name, className = ' ', onClick = () = >= {}}this.props
    return (
      <span className={`icon iconfont icon-The ${name} ${className} `}onClick={(e)= > onClick(e, 1)}></span>)}}Copy the code

ReactElement:

import React, { Dispatch, ReactElement } from 'react'
import Header from '.. /components/Header'
import Footer from '.. /components/Footer'
import { Switch, Route } from 'react-router-dom'
import { connect } from 'react-redux'
import Home from './Home'
import MyBooks from './MyBooks'
import Me from './Me'

interface IProps {
  onSetState: (key: string, value: any) = > void
  onDispatch: (action: Function) = > void
}

const Index = (props: IProps) = > {

  const renderComponent = (Component: ReactElement, title: string) = > {
    setTimeout(() = > {
      props.onSetState('title', title)
    })
    
    return Component
  }

  return (
    <div className="m-wrap">
      <Header></Header>
      <Switch>
        <Route path="/index/home" render={()= > renderComponent(<Home></Home>, 'Xiaomi Book City ')}></Route>
        <Route path="/index/my_books" render={()= > renderComponent(<MyBooks></MyBooks>, 'My bag ')}></Route>
        <Route path="/index/me" render={()= > renderComponent(<Me></Me>, 'Personal center ')}></Route>
      </Switch>
      <Footer></Footer>
    </div>)}const mapStateToProps = () = > {
  return{}}const mapDispatchToProps = (dispatch: Dispatch<any>) = > {
  return {
    onSetState(key: string, value: any) {
      dispatch({ type: 'SET_STATE', key, value })
    },
    onDispatch(action: Function) {
      dispatch(action)
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Index)
Copy the code

External declarations and triple slash directives

Declare: a statement

Reference: reference

Env: environment Environment

Namespace: indicates the namespace

The module, the module

External declarations are typically for third-party libraries of unknown provenance, and are needed when you want to use third-party libraries written in javascript code in your typescript projects. For a common example, suppose we introduce global ‘jQuery’ in HTML via the ‘script’ tag:

// Register the global variable $
<script src="path/to/jquery.js"></script>
Copy the code

The path/to/jquery.js file introduces the object ‘$’ in the global scope, and the TypeScript compiler will report an error if you use’ $’ in a TypeScript file in the same project:

// Error, missing declaration information for name $
// error TS2581: Cannot find name '$'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`
$('body').html('hello world');
Copy the code

Since there is no type information, the TypeScript compiler has no idea what ‘$’ stands for, and needs to introduce ** external declarations ** (since’ $’ is introduced into TypeScript code by external JavaScript). The keywords for external declarations are:

Parse statement ‘$(‘body’).html(‘hello world’); ` concluded:

  • – ‘$’ is a function that takes a string argument
  • The return value of the – ‘$’ call is an object that has the member function’ HTML ‘, whose arguments are also strings
// Declare the type of $
declare let $: (selector: string) = > {
 html: (content: string) = > void;
};

// Yes, $has been declared externally
$('body').html('hello world');
Copy the code

The declaration should be a pure description of the type or appearance of an identifier **, which is easy for the compiler to recognize. External declarations have the following characteristics:

  • – External declarations must be decorated with ‘DECLARE’
  • – Cannot contain implementation or initialization information (internal declarations can include implementation or initialization at the time of declaration)
// declare a as a number
declare let a: number;
// Error, external declaration cannot be initialized
// error TS1039: Initializers are not allowed in ambient contexts
declare let b: number = 2;

// Declare T as an interface
declare interface T {}
// Declare the interface type variable b
let b: T;

// declare fn as a function
// Error, declaration contains function implementation
// error TS1183: An implementation cannot be declared in ambient contexts
declare function fn(){}

// Correct, no function body implementation is included
declare function fn() :void;

// declare myFunc as a function
declare let myFunc: (a: number) = > void;

MyEnum Enum type
declare enum MyEnum {
 A, B
}

// declare NS as the namespace
declare namespace NS {
 // Error stating that initialization cannot be performed
 // error TS1039: Initializers are not allowed in ambient contexts
 const a: number = 1;
 // Correct, contains only declarations
 const b: number;
 // Correct, function does not contain function body implementation
 function c() :void;
}

// Declare a class
declare class Greeter {
 constructor(greeting: string);
 greeting: string;
 showGreeting(): void;
}
Copy the code

External declarations can also be used to declare a ** module **. If a member of an external module is to be accessed externally, the module member should be exported with the ‘export’ declaration:

declare module 'io' {
 export function read(file: string) :string;
 export function write(file: string, data: string) :void;
}
Copy the code

It is customary to write external declarations in a declaration file with the suffix ‘.d.ts’ and then import them with a triple slash instruction

/ / jquery. Which s file
declare let $: (selector: string) = > {
 html: (content: string) = > void;
};

/ / the main ts file
/// <reference path="./jquery.d.ts" />
$('body').html('hello world');
Copy the code

This statement declares that ‘main.ts’ depends on’ jquery.d.ts’. At compile time, the dependent file ‘jquery.d.ts’ will be included, just as the source of the dependent file is expanded in the dependency declaration:

// the main.ts file is equivalent to expanding the code at the triple slash instruction
declare let $: (selector: string) = > {
 html: (content: string) = > void;
};
$('body').html('hello world');
Copy the code

Note the difference between ‘path’ and ‘types’ in the three slash directive:

/// <reference path="./jquery.d.ts" />
/// <reference types="node" />
Copy the code
  • The – ‘path’ type declares a dependency on local files and contains path information
  • The – ‘types’ type declares a dependency on the types in the’ node_modules/@types’ folder and does not contain path information

 

 

///
directive declares a dependency on a package.

For example, introducing ///
to the declaration file indicates that the file uses the name declared in @types/node/index.d.ts; Also, this package needs to be included with the declaration file at compile time.

Use this directive only if you need to write a D.ts file.

Reference links:

Zhongsp. Gitbook. IO/typescript -…

www.teaspect.com/detail/5586

TS+Webpack

webpack.config.js:

module.exports = {
  mode: 'development'.entry: './src/main.ts'.output: {
    path: __dirname + '/dist'.filename: 'bundle.js'
  },
  devtool: "source-map".resolve: {
    extensions: [ ".ts"]},module: {
    rules: [{test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "ts-loader"}]}}Copy the code

package.json:

{
  "name": "m-ts-webpack"."version": "1.0.0"."description": ""."main": "webpack.config.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": ""."license": "ISC"."dependencies": {
    "ts-loader": "^ 7.0.2"."typescript": "^ 3.8.3"."webpack": "^ 4.43.0"."webpack-cli": "^ 3.3.11." "}}Copy the code

Project Code:

Github.com/baweireact/…

Yarn Clear the cache and uninstall the global installation package

yarn cache clean

yarn global remove @vue/cli

yarn global add @vue/cli
Copy the code

24. NPM download or YARN download to modify scaffolding

25. Countdown

interface IObj {
  endtime: string,
  wrapper: HTMLElement
}

class CountDown {
  endtime: string
  wrapper: HTMLElement
  constructor(obj: IObj) {
    this.endtime = obj.endtime
    this.wrapper = obj.wrapper
  }
  start() {
    setInterval(() = > {
      let start = new Date().getTime()
      let end = new Date(this.endtime).getTime();
      let result = end - start
      let time = this.formatDateTime(result)
      console.log(time)
      this.wrapper.innerHTML = time
    }, 1000)}formatDateTime(shijiancha: number) {
    let days = shijiancha / 1000 / 60 / 60 / 24;
    let daysRound = Math.floor(days);
    let hours = shijiancha / 1000 / 60 / 60 - (24 * daysRound);
    let hoursRound = Math.floor(hours);
    let minutes = shijiancha / 1000 / 60 - (24 * 60 * daysRound) - (60 * hoursRound);
    let minutesRound = Math.floor(minutes);
    let seconds = shijiancha / 1000 - (24 * 60 * 60 * daysRound) - (60 * 60 * hoursRound) - (60 * minutesRound);

    return 'Limited time sale${daysRound}day${hoursRound}when${minutesRound}pointsThe ${Math.floor(seconds)}Second `}}let countDown = new CountDown({ endtime: '2020/10/1'.wrapper: document.getElementById('box') as HTMLElement })
countDown.start()
Copy the code

 

Find the longest word in an English sentence

function longest(str? :string) {
  if (typeof str === 'undefined') {
    alert('No argument passed')
    return
  }
  let arr = str.split(' ')
  let result = 0
  let longestWord = ' '
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].length > result) {
      result = arr[i].length
      longestWord = arr[i]
    }
  }
  console.log('The longest word is:${longestWord}`)
  return result
}

let result = longest('let life be beautiful like summer flowers')
console.log(result)

longest()
Copy the code

 

 

 

 

 

 

 

 

Reference links:

Embrace the power of TypeScript with the Ts+Vue complete tutorial

Chinese manual

English manual

Introductory tutorial

Decorator —- Ruan Yifeng

Learn React with TypeScript 3

Link: pan.baidu.com/s/1BriHov6-… Extraction code: 7ERX