install
install
npm install -g typescript
Open project folder
tsc -init
compile
tsc ts01.ts
Listening and compiling
tsc -w
Listen and compile a file
tsc -w ts01.ts
Modify the location and target syntax of the compiled JS
Open tsconfig JSON, modify the value of outDir and uncomment it
{ "compilerOptions": { "target": "es3", "outDir": "./js/" } }
It will be converted to ES6 by default. It is recommended to convert to ES3 or ES5 to be compatible with most browsers.
grammar
data type
let num: number = 1; let str: string = "hello"; let b: boolean = true; let n: null = null; let un: undefined = undefined; let f: any = 1; // Get type console.log("typeof(str):"+typeof(str)) // array let arr1: Array<number> = [1, 2, 3]; let arr2: number[] = [1, 2, 3]; let arr3: string[] = ["aa", "bb", "cc"]; let arr4: Array<number | string> = [1, "aa", 3]; // tuple let tup: [string, string, number] = ['Dylan', 'male', 23]; console.log("typeof(tup):"+typeof(tup))
What is the difference between arrays and tuples?
A tuple can be understood as an array with a fixed length and each element type determined.
Let's look at an example
let tup: [string, string, number] = ['Dylan', 'male', 23]; tup.push("123"); tup[3] = 123;
Example 2
let tup: [string, string, number] = ['Dylan', 'male', 23]; tup.pop(); tup[2] = 456;
In this example, we can find several problems with tuples:
- Although the length is fixed, we can push the element so that its length exceeds the defined length without error. However, the subscript value cannot exceed the defined length.
- If the push exceeds the length, the converted js can run normally, and the print result also contains elements exceeding the length, so it is not recommended to add elements through push, but set them through subscript.
- When push ing, the data type can be the type included in the definition, and cannot be other types.
- When assigning values according to subscripts, the type must be the same as when defining.
- After pop deletes elements, we can still assign values through subscripts.
class
Implementation of interface class integration and method overloading of interface class
interface Person { run():void; } class Men implements Person { name: string; age: number; constructor(name:string,age:number) { this.name = name; this.age = age; } run(): void { console.log("run"); } talk(): void; talk(str:string): void; talk(num:number): void; talk(str:string,num:number): void; talk(par1?:any,par2?:any) { if (par1 == undefined && par2 == undefined) { console.log("method 1"); } else if (par2 == undefined) { if (typeof par1 == "string") { console.log("method 2"); } else if (typeof par1 == "number") { console.log("method 3"); } } else { console.log("method 4"); } } } class SuperMen extends Men{ } let men = new Men("Xiao Ming", 18); men.talk(); men.talk("Xiao Ming"); men.talk(18); men.talk("Xiao Ming",18);
The results can be seen
method 1 method 2 method 3 method 4
VUE2 integrated TS
When creating a new project, you can directly select ts. this is mainly about the upgrading of old projects.
Installation dependency
npm i vue-class-component vue-property-decorator --save npm i ts-loader typescript tslint tslint-loader tslint-config-standard -D
Configure Vue config. JS add the following code
module.exports = { configureWebpack: { resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }, module: { rules: [ { test: /\.ts$/, exclude: /node_modules/, enforce: 'pre', loader: 'tslint-loader' }, { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], } } ] } }, }
New tsconfig JSON is placed in the project root directory
{ "compilerOptions": { "allowJs": true, "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "experimentalDecorators": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "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" ] }
Add two TS files in the src root directory
shims-tsx.d.ts
// shims-tsx. d. TS SRC directory 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 extends Vue {} interface IntrinsicElements { [elem: string]: any; } } }
Create a new hips Vue d.ts
// shims-vue. d. TS SRC directory declare module '*.vue' { import Vue from 'vue'; export default Vue; } //Adaptation definition file for TypeScript because vue file is not a regular file type, //TypeScript cannot understand what vue files are for. This paragraph is added to tell TypeScript that vue files are of this type. //Without this file, you will find all the files imported by import vue files will report errors. //axios error declare module 'axios' { interface AxiosInstance { (config: AxiosRequestConfig): Promise<any> } }
Add tslint json
{ "extends": "tslint-config-standard", "globals": { "require": true } }
main.js to main TS configure Vue config. JS entry is main ts
pages: { index: { entry: 'src/main.ts', } },
Install @ typescript eslint / parser
Change the eslint check to @ typescript eslint / parser
npm install @typescript-eslint/parser --save
Change eslintrc.js
parserOptions: { parser: '@typescript-eslint/parser' },
Code format
Comparison of old and new writing methods
Original writing
<script> export default { name: 'xx',// Component name components: {},// assembly props: {},// Value passed from parent component data() { // attribute return {}; }, computed:{}, // Calculation properties watch:{},// monitor mounted() {}, // Life cycle hook function methods: {} // method }; </script>
New writing (TS)
<template> <div class="home"> <HelloWorld :msg="message" /> {{ computedMsg }} </div> </template> <script lang="ts"> import { Component, Prop, Vue, Watch, Emit } from "vue-property-decorator"; import HelloWorld from "@/components/HelloWorld.vue"; @Component({ components: { HelloWorld, }, }) export default class Home extends Vue { // props @Prop({ type: Number, default: 1, required: false, }) propA?: number; @Prop() propB?: string; // data public message = "Hello TS"; // computed public get computedMsg(): string { return "Here is the calculation attribute" + this.message; } // watch property @Watch("propA", { deep: true, }) public test(newValue: string, oldValue: string): void { console.log("propA The value has changed" + newValue + " oldValue:" + oldValue); } // $emit // Original writing: this$ emit('mysend',this.message) // Now write this directly bindSend() @Emit("mysend") bindSend(): string { return this.message; } // mounted lifecycle hook function mounted(): void { console.info("mounted"); this.mymethod(); } // Methods in methods public mymethod(): void { this.bindSend(); } } </script>
$emit
contrast
count = 0 // this.count += n; this.$emit('add-to-count', n) @Emit("add-to-count") addToCount(n: number) { this.count += n; } // this.count = 0; this.$emit('reset'); @Emit("reset") resetCount() { this.count = 0; } // this.$emit('return-value', 10) @Emit('return-value') returnValue() { return 10; } // Equivalent to this$ emit('on-input-change', num+1, num) @Emit("on-input-change") onInputChange(num: number) { return num + 1; } // amount to // const promise = new Promise((resolve) => { // setTimeout(() => { // resolve(20) // }, 0) // }) // // promise.then((value) => { // this.$emit('promise', value) // }) @Emit() promise() { return new Promise((resolve) => { setTimeout(() => { resolve(20); }, 0); }); }
As can be seen from the above example
Unless the alias of the $emit method is set. The return value of the method is $emit, the second parameter. The parameter passed by the method is the third parameter of $emit. If the method has no return value, it is the second parameter. The execution order is to execute the code in the method body first, and then $emit.