怎么做收费网站,猎聘网招聘官网app,wordpress 局域网 慢,域名个人备案查询文章目录 基础知识基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)enum(枚举): 定义一个可枚举的对象typeinterface联合类型: |交叉类型: any 类型null 和 undefinednullundefined never类型 面试题及实战1. 你觉得使用ts的好处… 文章目录 基础知识基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)enum(枚举): 定义一个可枚举的对象typeinterface联合类型: |交叉类型: any 类型null 和 undefinednullundefined never类型 面试题及实战1. 你觉得使用ts的好处是什么?2. type 和 interface的异同3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?4. 什么是泛型, 泛型的具体使用?5. 写一个计算时间的装饰器6. 写一个缓存的装饰器7. 实现一个路由跳转 通过ts约束参数的routeHelper8. 实现一个基于ts和事件模式的countdown基础类使用 9. npm install一个模块都发生了什么10. eventemitter3 执行ts文件命令
tsc 文件.ts 基础知识
基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)
类型关键字描述任意类型any声明为 any 的变量可以赋予任意类型的值。数字类型number双精度64位浮点值, 它可以用来表示整数和分数let num: number 666;字符串类型stringlet str: string 呀哈哈;布尔类型booleanlet flag: boolean true;数组类型无声明变量为数组在元素类型后面加[]: let arr: number[] [1,2];, 或使用数组泛行: let arr:Arraynumber [1,2];元组无元组类型用来表示已知元素数量和类型的数组, 各元素的类型不必相同, 对应位置的类型需要相同: let x:[string,number]; 正确: x [呀哈哈, 2];错误: x [2, 呀哈哈];枚举enum枚举类型用于定义数值集合 enum Color {Red, Green, Blue}; let c : Color Color.Blue;console.log(c); // 2voidvoid用于标识方法返回值的类型, 表示该方法没有返回值 function hello(): void{ alert(Hello World); }nullnull表示对象值缺失undefinedundefined用于初始化变量为一个未定义的值nevernevernever是其他类型(包括 null 和 undefined) 的子类型, 代表从不会出现的值.
enum(枚举): 定义一个可枚举的对象
const obj {RUN:run,EAT:eat
}
enum Obj {RUN,// 默认 RUN 0EAT, // 默认 EAT 1ABC abc, // 使用 复制
}
// 使用
const eat Obj.EAT;const getValue () {return 0
}enum List {A getValue(),B 2, // 此处必须要初始化值不然编译不通过C
}
console.log(List.A) // 0
console.log(List.B) // 2
console.log(List.C) // 3type
type Action eat | run;
// 声明 a 变量类型为 Action, 可选值为eat, run
const a:Action eat;interface
interface data {name: string,age: number
};
const b: data {name: yhh,age: 10
}
// 定义axios.post 返回值类型
axios.postdata().then();联合类型: |
交叉类型:
any 类型
任意值是 typescript 针对编程时类型不明确的变量使用的一种数据类型. 常用于以下三种情况
// 变量的值会动态改变时, 比如来着用户的输入, 任意值类型可以让这些变量跳过编译阶段的类型检查
let x: any 1;
x yhh;
x false;// 改写现有代码时, 任意值允许在编译时可选择地包含或移除类型检查
let x: any 4;
x.isEmpty(); // 正确, isEmpty方法在运行时可能存在, 但这里并不会检查
x.toFixed(); // 正确// 定义存储各种类型数据的数组时
ler arrayList: any[] [1,false,fine];
arratList[1] 100;null 和 undefined
null
null 在 JavaScript 中 表示’什么都没有’.
null 是一个只有一个值的特殊类型, 表示一个空对象引用.
用 typeof 检测 null 返回是 object.
undefined
undefined 在 javascript 中是一个没有设置值的变量.
typeof 一个没有值的变量会返回 undefined.
Null 和 Undefined 是其他任何类型(包括void)的子类型. 可以赋值给其他类型, 比如数字类型, 赋值后的类型会变成 null 或 undefined.
在 typescript 中启用严格的空检验(--strictnullChecks)特性, 就可以使 null 和 undefined 只能被赋值给 void 或本身对应的类型.
// 启用 --strictnullChecks
let x : number;
x 1;
x undefined; // 错误, 因为 x 只能是数字类型
x null; // 错误// 如果一个类型可能出现 null 或 undefined, 可以使用 | 类支持多中类型
// 启用 --strictnullChecks
let x : number | null | undefined;
x 1;
x undefined; // 正确
x null; // 正确never类型
never 是其他类型(包括null和undefined)的子类型, 代表从不会出现的值. 这意味着声明never类型的变量只能被never类型所赋值, 在函数中通常表现为抛出异常或无法执行到终止点.
let x : never;
let y : number;x 123; // 错误, 数字类型不可转为 never 类型// 正确, never 类型可以赋值给 never类型
x ((){ throw new Error(exception) })();
// 正确, never 类型可以赋值给 数字类型
y ((){ throw new Error(exception) })();// 返回值为 never 的函数可以是抛出异常的情况
function error(message:string): never{throw new Error(message);
}
// 返回值为 never 的函数可以是无法被执行到终止点的情况
function loop(): never{while (true){}
}面试题及实战
1. 你觉得使用ts的好处是什么?
1.1 TypeScript是JavaScript的加强版它给JavaScript添加了可选的静态类型和基于类的面向对象编程它拓展了JavaScript的语法。所以ts的功能比js只多不少. 1.2 Typescript 是纯面向对象的编程语言包含类和接口的概念. 1.3 TS 在开发时就能给出编译错误 而 JS 错误则需要在运行时才能暴露。 1.4 作为强类型语言你可以明确知道数据的类型。代码可读性极强几乎每个人都能理解。 1.5 ts中有很多很方便的特性, 比如可选链.
2. type 和 interface的异同
重点用interface描述数据结构用type描述类型
2.1 都可以描述一个对象或者函数
interface User {name: stringage: number
}interface SetUser {(name: string, age: number): void;
}type User {name: stringage: number
};type SetUser (name: string, age: number) void;2.2 都允许拓展extends interface 和 type 都可以拓展并且两者并不是相互独立的也就是说 interface 可以 extends type, type 也可以 extends interface 。 虽然效果差不多但是两者语法不同。
// interface extends interface
interface Name { name: string;
}
interface User extends Name { age: number;
}// type extends type
type Name { name: string;
}
type User Name { age: number };// interface extends type
type Name { name: string;
}
interface User extends Name { age: number;
}// type extends interface
interface Name { name: string;
}
type User Name { age: number;
}2.3 只有type可以做的
type 可以声明基本类型别名联合类型元组等类型
// 基本类型别名
type Name string// 联合类型
interface Dog {wong();
}
interface Cat {miao();
}type Pet Dog | Cat// 具体定义数组每个位置的类型
type PetList [Dog, Pet]// 当你想获取一个变量的类型时使用 typeof
let div document.createElement(div);
type B typeof div3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?
首先可以通过Pick和Omit
interface Test {name: string;sex: number;height: string;
}type Sex PickTest, sex;const a: Sex { sex: 1 };type WithoutSex OmitTest, sex;const b: WithoutSex { name: 1111, height: sss };比如Partial, Required.
再者可以通过泛型.
4. 什么是泛型, 泛型的具体使用?
泛型是指在定义函数、接口或类的时候不预先指定具体的类型使用时再去指定类型的一种特性。
可以把泛型理解为代表类型的参数
interface TestT any {userId: T;
}type TestA Teststring;
type TestB Testnumber;const a: TestA {userId: 111,
};const b: TestB {userId: 2222,
};
5. 写一个计算时间的装饰器
export function before(beforeFn: any) {return function(target: any, name: any, descriptor: any) {const oldValue descriptor.value;descriptor.value function() {beforeFn.apply(this, arguments);return oldValue.apply(this, arguments);};return descriptor;};
}export function after(afterFn: any) {return function(target: any, name: any, descriptor: any) {const oldValue descriptor.value;descriptor.value function() {const ret oldValue.apply(this, arguments);afterFn.apply(this, arguments);return ret;};return descriptor;};
}
// 计算时间
export function measure(target: any, name: any, descriptor: any) {const oldValue descriptor.value;descriptor.value async function() {const start Date.now();const ret await oldValue.apply(this, arguments);console.log(${name}执行耗时 ${Date.now() - start}ms);return ret;};return descriptor;
}
6. 写一个缓存的装饰器
const cacheMap new Map();export function EnableCache(target: any, name: string, descriptor: PropertyDescriptor) {const val descriptor.value;descriptor.value async function(...args: any) {const cacheKey name JSON.stringify(args);if (!cacheMap.get(cacheKey)) {const cacheValue Promise.resolve(val.apply(this, args)).catch((_) cacheMap.set(cacheKey, null));cacheMap.set(cacheKey, cacheValue);}return cacheMap.get(cacheKey);};return descriptor;
}7. 实现一个路由跳转 通过ts约束参数的routeHelper
import { Dictionary } from vue-router/types/router;
import Router, { RoutePath } from ../router;export type BaseRouteType Dictionarystring;export interface IndexParam extends BaseRouteType {name: string;
}export interface AboutPageParam extends BaseRouteType {testName: string;
}export interface UserPageParam extends BaseRouteType {userId: string;
}export interface ParamsMap {[RoutePath.Index]: IndexParam;[RoutePath.About]: AboutPageParam;[RoutePath.User]: UserPageParam;
}export class RouterHelper {public static replaceT extends RoutePath(routePath: T, params: ParamsMap[T]) {Router.replace({path: routePath,query: params,});}public static pushT extends RoutePath(routePath: T, params: ParamsMap[T]) {Router.push({path: routePath,query: params,});}
}8. 实现一个基于ts和事件模式的countdown基础类
import { EventEmitter } from eventemitter3;export interface RemainTimeData {/** 天数 */days: number;/*** 小时数*/hours: number;/*** 分钟数*/minutes: number;/*** 秒数*/seconds: number;/*** 毫秒数*/count: number;
}export type CountdownCallback (remainTimeData: RemainTimeData, remainTime: number) void;enum CountdownStatus {running,paused,stoped,
}
// 练习
interface User {name: stringage: number
}
function testT extends User(params: T): T{return params
}
test({name:1,age:1});export enum CountdownEventName {START start,STOP stop,RUNNING running,
}
interface CountdownEventMap {[CountdownEventName.START]: [];[CountdownEventName.STOP]: [];[CountdownEventName.RUNNING]: [RemainTimeData, number];
}export function fillZero(num: number) {return 0${num}.slice(-2);
}export class Countdown extends EventEmitterCountdownEventMap {private static COUNT_IN_MILLISECOND: number 1 * 100;private static SECOND_IN_MILLISECOND: number 10 * Countdown.COUNT_IN_MILLISECOND;private static MINUTE_IN_MILLISECOND: number 60 * Countdown.SECOND_IN_MILLISECOND;private static HOUR_IN_MILLISECOND: number 60 * Countdown.MINUTE_IN_MILLISECOND;private static DAY_IN_MILLISECOND: number 24 * Countdown.HOUR_IN_MILLISECOND;private endTime: number;private remainTime: number 0;private status: CountdownStatus CountdownStatus.stoped;private step: number;constructor(endTime: number, step: number 1e3) {super();this.endTime endTime;this.step step;this.start();}public start() {this.emit(CountdownEventName.START);this.status CountdownStatus.running;this.countdown();}public stop() {this.emit(CountdownEventName.STOP);this.status CountdownStatus.stoped;}private countdown() {if (this.status ! CountdownStatus.running) {return;}this.remainTime Math.max(this.endTime - Date.now(), 0);this.emit(CountdownEventName.RUNNING, this.parseRemainTime(this.remainTime), this.remainTime);if (this.remainTime 0) {setTimeout(() this.countdown(), this.step);} else {this.stop();}}private parseRemainTime(remainTime: number): RemainTimeData {let time remainTime;const days Math.floor(time / Countdown.DAY_IN_MILLISECOND);time time % Countdown.DAY_IN_MILLISECOND;const hours Math.floor(time / Countdown.HOUR_IN_MILLISECOND);time time % Countdown.HOUR_IN_MILLISECOND;const minutes Math.floor(time / Countdown.MINUTE_IN_MILLISECOND);time time % Countdown.MINUTE_IN_MILLISECOND;const seconds Math.floor(time / Countdown.SECOND_IN_MILLISECOND);time time % Countdown.SECOND_IN_MILLISECOND;const count Math.floor(time / Countdown.COUNT_IN_MILLISECOND);return {days,hours,minutes,seconds,count,};}
}使用
templatediv classhome clicktoAboutPageimg altVue logo src../assets/logo.pngHelloWorld msgWelcome to Your Vue.js TypeScript App/div倒计时{{timeDisplay}}/div/div
/templatescript langts
import { Component, Vue } from vue-property-decorator;
import HelloWorld from ../components/HelloWorld.vue;
import { RouterHelper } from ../lib/routerHelper;
import { Countdown, CountdownEventName, fillZero } from ../lib/countdown;
import { RoutePath } from ../router;
import { measure } from ../decorator;Component({components: {HelloWorld,},
})
export default class Home extends Vue {public timeDisplay: string ;measurepublic toAboutPage() {RouterHelper.push(RoutePath.About, { testName: 1111 });}public created() {const countdown new Countdown(Date.now() 60 * 60 * 1000, 10);countdown.on(CountdownEventName.RUNNING, (remainTimeData) {const { hours, minutes, seconds, count} remainTimeData;this.timeDisplay [hours, minutes, seconds, count].map(fillZero).join(:);});}
}
/script
9. npm install一个模块都发生了什么
npm install命令输入 检查node_modules目录下是否存在指定的依赖 如果已经存在则不必重新安装 若不存在继续下面的步骤 向 registry本地电脑的.npmrc文件里有对应的配置地址查询模块压缩包的网址 下载压缩包存放到根目录里的.npm目录里 解压压缩包到当前项目的node_modules目录中。
10. eventemitter3