TypeScript TS 环境与常用命令 1. 环境安装:
1 npm install -g typescript
2. 常用命令:
编译 ts 文件:
编译完成后会生成同名 js 文件,使用 node 命令 node demo.js
执行文件。
监听 ts 文件变化并及时编译:
生成 tsconfig.json 配置文件:
此命令会在当前文件夹中生成 ts 配置文件,并且执行 tsc
命令会自动根据 tsconfig.json 配置编译当前文件夹以及子文件夹中的所有 ts 文件。
执行 tsc -w
会监听当前文件夹内(包括子文件夹)的所有 ts 文件并及时编译。
配置文件中 "outDir": "./"
可以指定文件编译后所在位置。
3. ts-node: ts-node (非必要安装)可以直接运行 ts 文件不需要我们先编译在执行。
tsconfig.json tsconfig.json 是 TypeScript 的配置文件,其中常见配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 { "compilerOptions" : { "module" : "commonjs" , "target" : "ES5" , "sourceMap" : true , "lib" : [ "ES6" ] , "outDir" : "./build" , "outFile" : "./build/app.js" , "allowJs" : true , "checkjs" : true , "removeComments" : true , "noEmit" : true , "noEmitOnError" : true , "alwaysStrict" : true , "noImplicitAny" : true , "noImplicitReturns" : true , "noImplicitThis" : true , "strictNullChecks" : true , "strict" : false , } , "include" : [ "./src/**/*" , ] , "exclude" : [ "node_modules" , ] , "files" : [ ] }
注意使用命令行模式 tsc fileName.ts
方式编译会忽略 tsconfig 配置。
TypeScript 语法 1. 基础类型:
类型声明与基础语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 let test; test = true ; test = "str" ; let str :string = "str" ; let isTrue = true ; function add (num1:number , num2:number ):number { return num1 + num2; } let sum = add (1 , 1 ); let info : string |number ; let arr : (string |number )[]; let num :10 ; let sex :"nan" |"nv" ;
TS 的基础类型:
数据类型
关键字
描述
数字
number
let num:number = 1;
字符串
string
let str:string = "str";
布尔
boolean
let flag:boolean = true;
数组
Array 或 []
let arr:number[];
或 let arr:Array<number>;
元组
let arr:[number, string]
数组长度限定且位置指定类型
枚举
enum
enum Color {Red, Green}
使用: let c:Color = Color.Red;//1
void
void
标识方法返回值类型,表示该方法没有返回值
null
null
空值
undefined
undefined
变量为未定义的值
never
never
永远不会出现的值(方法中死循环、方法抛出异常)
any
any
任意类型
unknown
unknown
安全类型的 any(不能直接赋值给其它变量,可以赋值给 any)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 let test :unknown = 0 ;test = "str" ; let str :string = "str" ;if (typeof test === "string" ) { str = test; } str = test as string ; str = <string >test; let s :any = test; str = s;
1 2 3 let arr :[string ,number ][] = [ ["str" ,1 ], ];
1 2 3 type myType = string | number ;let val :myType = 0 ;
2. 对象与函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 let o = { name : "o" , } let user :{name :string , age?:number }; user = {name : "user" } let userinfo :{name :string , [name :string ]:any }userinfo = {name : "userinfo" , age : 18 , sex : "nv" }; let o : {name :string } & {age :number };o = {name :"o" , age :18 } let fun1 :(a:number , b:number ) => number ; fun1 = (a, b ) => a*b;
3. 断言(as): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function demo (n:string |number ) { let len :number ; len = (n as string ).length ; } let str = "str" as const ; str = "str" ; let arr = ["str" , 1 ] as const ; function ew ( ) { return ["str" , 1 ]; } let [a, b] = ew ();let body :HTMLBodyElement = document .querySelector ('body' )!;
3. TS 函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 type myFun = (n:number )=> void ;let fun :myFun = function (a:number ) {}let fun2 :(n?:number )=> void = ()=> {}; let fun3 :(...n:any [] )=> void = (...n:any [] )=> { console .log (n); }; function disp (s1:string ):void ; function disp (n1:number ,s1:string ):void ; function disp (x:any ,y?:any ):void { console .log (x); console .log (y); } disp ("abc" );disp (1 ,"xyz" );
4. 面向对象: 1. 类的基础: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Person { name : string ; constructor (name: string ) { this .name = name; } say (): void { console .log (this .name ); } } const person :Person = new Person ("class" );person.name = "John" ; person.say (); class Student extends Person { school :string ; constructor (name:string , school:string ) { super (name); this .school = school; } say (): void { super .say (); console .log (this .school + " " + this .name ); } } const student = new Student ("student" , "myScholl" );student.say ();
2. 访问修饰符: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Person { public name : string ; private _age : number ; protected sex : string ; readonly sfz : string ; static num : number ; public constructor (name: string ) { this .name = name; } public say (): void { console .log (this .name ); } }
3. 存取器: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Person { private _name : string ; public constructor (name: string ) { this ._name = name; } set name (name: string ) { this ._name = name; } get name (): string { return this ._name ; } } const person = new Person ("class" );person.name = "John" ; console .log (person.name );
4. 抽象类与接口:
抽象类:
1 2 3 4 5 6 7 8 9 10 11 12 abstract class Person { abstract name : string ; abstract run (): void ; } class User extends Person { public name : string = "" ; public run (): void {} }
接口(接口名称建议以大写 I 开头):
1 2 3 4 5 6 7 8 9 10 11 interface Person { name : string ; run (): void ; } class User implements Person { public name : string = "" ; public run (): void {} }
接口类型约束:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Person { name : string = 'John' ; age : number = 18 ; } const p :Person = new Person ();const p2 :Person = {name : 'hello' , age : 20 };type MyObj1 = {name :string , age :number };const myObj :MyObj1 = {name : 'hello' , age :20 };type MyObj2 = {name :string } | {age :number };type MyObj3 = {name :string } & {age :number };interface Interface1 { name : string ; age : number ; } const interface1 :Interface1 = {name : 'hello' , age :20 };interface A { name : string ; } interface A { age : number ; sex?: string ; } const a :A = {name : 'A' , age :20 };interface B { [key : number ]: string ; } const b :B = {1 : '1' , 2 : '2' , 3 : '3' };
5. 泛型: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function fun<T>(arg :T):T { return arg; } let num :number = fun<number >(1 );let o :{name :string } = fun<{name :string }>({name : "name" });let str :string = fun ("str" ); const fun2 = <T=number >(arg :T):T => arg;let num2 = fun2 (1 );interface ILength { length :number ; } function getLength<T extends ILength >(arg :T):number { return arg.length ; } getLength ("123" );getLength ({name : "1" , length : 1 });interface IA<T1=string ,T2=number > { name : T1 ; age : T2 ; } const ia1 :IA <number , number > = { name : 1 , age : 1 }const ia2 :IA = { name : "2" , age : 2 }
5. 命名空间:
同文件内:
1 2 3 4 5 6 7 8 9 10 11 namespace One { export function add (n:number ):number { return n; } } namespace Two { export function add (n:string ):string { return n; } } console .log (One .add (1 ));console .log (Two .add ("2" ));
不同文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export namespace One { export function add (n:number ):number { return n; } } export namespace Two { export function add (n:string ):string { return n; } } import { One } from './One' ;import { Two } from './Two' ;console .log (One .add (1 ));console .log (Two .add ("2" ));
还能添加子命名空间等。
描述文件声明
在某 js 文件中:
1 2 3 let ewhost = "1" ;function ewshop (n ){ return n }function Person ( ) { this .name = "John" ;}
config**.d.ts** 中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 declare let ewhost : string ; declare function ewshop (n:number ):number ; declare class Person {name :string ;}; declare namespace $ { export function get (url: string , fn:(res:object )=>void ): any ; } declare module "mymodule" { export function join (arr:any [] ):void ; } declare module "*.png" ;
DefinitelyTyped 中为我们提供好了常用的第三方 js 库的 .d.ts 配置文件,在 TypeScript: Search for typed packages (typescriptlang.org) 中搜索我们需要使用的库的配置文件然后安装即可。
Vue3 与 TS 1. shims-vue.d.ts: shims-vue.d.ts 是为了 typescript 做的适配定义文件,因为 vue 文件不是一个常规的文件类型,ts 是不能理解 vue 文件是干嘛的,加这一段是是告诉 ts,vue 文件是这种类型的:
1 2 3 4 5 6 declare module '*.vue' { import type { DefineComponent } from 'vue' const component : DefineComponent <{}, {}, any > export default component }
2. defineComponent:
原来 vue 中使用 export default {}
定义组件属性,对于编辑器而言 {} 只是一个 Object 的类型,无法有针对性的提示我们对于 vue 组件来说 {} 里应该有哪些属性。
在 TypeScript 中 {} 就变成了 defineComponent 的参数,那么对参数类型的提示,就可以实现对 {} 中属性的提示,外还可以进行对参数的一些类型推导等操作。
1 2 3 4 5 6 7 8 9 10 11 12 <script lang ="ts" > import { defineComponent } from 'vue' ;import HelloWorld from '@/components/HelloWorld.vue' ;export default defineComponent ({ components : { HelloWorld , }, }); </script >
3. 选项式 API: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import { defineComponent, PropType } from 'vue' ;interface User { name :string } export default defineComponent ({ props : { user : { type : Object as PropType <User >, default ():User { return { name : 'user' }; } } }, data ( ) { return { msg : 'Hello' as string , stu : Object as User , } }, mounted ():void { console .log (this .msg ); }, });
4. 组合式 API: 1 2 3 4 5 6 7 8 9 10 11 setup ( ) { interface User { name :string } const msg = ref<string >('hello' ); const stu = reactive<User >({name : 'user' }); onMounted (():void => { console .log (msg.value ); }); return { msg, stu, } }