TypeScript学习篇-类型介绍使用、ts相关面试题

文章目录

  • 基础知识
    • 基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)
      • enum(枚举): 定义一个可枚举的对象
      • type
      • interface
      • 联合类型: |
      • 交叉类型: &
      • any 类型
      • null 和 undefined
        • null
        • undefined
      • never类型
    • 面试题及实战
      • 1. 你觉得使用ts的好处是什么?
      • 2. type 和 interface的异同
      • 3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?
      • 4. 什么是泛型, 泛型的具体使用?
      • 5. 写一个计算时间的装饰器
      • 6. 写一个缓存的装饰器
      • 7. 实现一个路由跳转 通过ts约束参数的routeHelper
      • 8. 实现一个基于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:Array<number> = [1,2];
元组元组类型用来表示已知元素数量和类型的数组, 各元素的类型不必相同, 对应位置的类型需要相同:
let x:[string,number];
正确: x = ['呀哈哈', 2];
错误: x = [2, '呀哈哈'];
枚举enum枚举类型用于定义数值集合
enum Color {Red, Green, Blue};
let c : Color = Color.Blue;
console.log(c); // 2
voidvoid用于标识方法返回值的类型, 表示该方法没有返回值
function hello(): void{ alert('Hello World'); }
nullnull表示对象值缺失
undefinedundefined用于初始化变量为一个未定义的值
nevernevernever是其他类型(包括 null 和 undefined) 的子类型, 代表从不会出现的值.

enum(枚举): 定义一个可枚举的对象

const obj = {'RUN':'run','EAT':'eat'
}
enum Obj {'RUN',// 默认 RUN = 0'EAT', // 默认 EAT = 1'ABC' = '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) // 3

type

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.post<data>().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

nullJavaScript 中 表示’什么都没有’.

null 是一个只有一个值的特殊类型, 表示一个空对象引用.

typeof 检测 null 返回是 object.

undefined

undefinedjavascript 中是一个没有设置值的变量.

typeof 一个没有值的变量会返回 undefined.

NullUndefined 是其他任何类型(包括void)的子类型. 可以赋值给其他类型, 比如数字类型, 赋值后的类型会变成 nullundefined.

typescript 中启用严格的空检验(--strictnullChecks)特性, 就可以使 nullundefined 只能被赋值给 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 是其他类型(包括nullundefined)的子类型, 代表从不会出现的值. 这意味着声明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 div

3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?

首先可以通过Pick和Omit

interface Test {name: string;sex: number;height: string;
}type Sex = Pick<Test, 'sex'>;const a: Sex = { sex: 1 };type WithoutSex = Omit<Test, 'sex'>;const b: WithoutSex = { name: '1111', height: 'sss' };

比如Partial, Required.

再者可以通过泛型.

4. 什么是泛型, 泛型的具体使用?

泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。

可以把泛型理解为代表类型的参数

interface Test<T = any> {userId: T;
}type TestA = Test<string>;
type TestB = Test<number>;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 = Dictionary<string>;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 replace<T extends RoutePath>(routePath: T, params: ParamsMap[T]) {Router.replace({path: routePath,query: params,});}public static push<T 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 test<T 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 EventEmitter<CountdownEventMap> {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,};}
}
使用
<template><div class="home" @click="toAboutPage"><img alt="Vue logo" src="../assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/><div>倒计时:{{timeDisplay}}</div></div>
</template><script lang="ts">
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Robot Operating System——内部审查(Introspection)Service

大纲 introspection_service检验Parameter值和类型修改内部审查&#xff08;Introspection&#xff09;功能的状态完整代码 introspection_client完整代码 测试参考资料 在ROS 2&#xff08;Robot Operating System 2&#xff09;中&#xff0c;内部审查&#xff08;Introspect…

【中项】系统集成项目管理工程师-第7章 软硬件系统集成-7.3软件集成

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

python 裁剪图片

情况&#xff1a; 有时候看视频&#xff0c;看到一个漂亮的妹子&#xff0c;按下 Alt PrintScreen 进行截图之后&#xff0c;会把整个屏幕都截图。 需要适当剪裁一下。 每次打开 PS &#xff0c; 也太慢了。 所以写个代码&#xff0c; 快速处理。 效果对比&#xff1a; 原始…

【2025留学】德国留学真的很难毕业吗?为什么大家不来德国留学?

大家好&#xff01;我是德国Viviane&#xff0c;一句话讲自己的背景&#xff1a;本科211&#xff0c;硕士在德国读的电子信息工程。 之前网上一句热梗&#xff1a;“德国留学三年将是你人生五年中最难忘的七年。”确实&#xff0c;德国大学的宽进严出机制&#xff0c;延毕、休…

OOP知识整合----集合

目录 一、定义 1、集合: ( 不限制长度&#xff0c;存多少是多少) 2、集合框架: 二、List集合中常用的方法 1、Boolean add(Object o) 2、void add(int index,Object o) 3、Boolean remove(Object o) 4、Object remove(int index) 5、int size() 6、Boolean conta…

Code Effective学习笔记--第8章防御式编程

这一章聚焦如何通过断言和Java的异常处理机制这些防御式编程的方法来提高程序的健壮性和安全性&#xff0c;这是防御式编程技术的方面。但是健壮性和安全性到了一定的程度其实是矛盾的&#xff0c;健壮性意味着对于任何的输入&#xff0c;程序都不会终止而且都能给出返回&#…

Tftp服务器环境搭建

1、什么是Tftp TFTP&#xff08;Trivial File Transfer Protocol&#xff0c;简单文件传输协议&#xff09;是一种基于UDP&#xff08;User Datagram Protocol&#xff09;的文件传输协议&#xff0c;它被设计为一个非常简单的文件传输机制&#xff0c;特别适用于那些对复杂性有…

make2exe:自动集成测试

模板Makefile&#xff0c;生成多个C/C模块的集成测试程序。

免费【2024】springboot 基于微信小程序的宠物服务中心

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

JavaDS —— 二叉搜索树、哈希表、Map 与 Set

前言 我们将学习 Map 与 Set 这两个接口下的 TreeMap 与 TreeSet &#xff0c;HashMap 与 HashSet &#xff0c;在学习这四个类使用之前&#xff0c;我们需要先学习 二叉搜索树与 哈希表的知识。 二叉搜索树 在学习二叉树的时候&#xff0c;我们就已经了解过二叉搜索树的概念…

酒店智能门锁接口pro[0922]D801 对接收银-SAAS本地化-未来之窗行业应用跨平台架构

proUSB接口函数[0922中性版]-D801 调用函数库&#xff1a; 提供Windows下的32位动态连接库proRFL.DLL&#xff0c;函数使用详细说明 //-----------------------------------------------------------------------------------// 功能&#xff1a;读DLL版本&#xff0c;不涉…

【Linux C | 网络编程】进程池退出的实现详解(五)

上一篇中讲解了在进程池文件传输的过程如何实现零拷贝&#xff0c;具体的方法包括使用mmap&#xff0c;sendfile&#xff0c;splice等等。 【Linux C | 网络编程】进程池零拷贝传输的实现详解&#xff08;四&#xff09; 这篇内容主要讲解进程池如何退出。 1.进程池的简单退…

Java并发编程(上)

并发&#xff1a;多个线程&#xff08;进程&#xff09;竞争一个资源 并行&#xff1a;多个线程&#xff08;进程&#xff09;同时运行不同资源 线程和进程的关系简单地说&#xff0c;进程是一个容器&#xff0c;一个进程中可以容纳若干个线程&#xff0c;一个进程里面&#…

微信小程序入门

创建一个入门程序 这是index.vxml代码 <!--index.wxml--> <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <view class"container" ><view&…

苹果CMS:资源采集站如何设置定时采集详细教程讲解

我们搭建好站点之后&#xff0c;会自定义一些采集&#xff0c;但是需要每天去手动执行&#xff0c;有时候甚至会忘记&#xff0c;那我们如何处理呢&#xff1f;今天我们就来介绍一下如何设置定时器。 如果按照官方例子来设置定时器会遇到一个问题就是采集的资源未绑定类型&…

WAF+API安全代表厂商|瑞数信息入选IDC报告《生成式AI推动下的中国网络安全硬件市场现状及技术发展趋势》

近日&#xff0c;全球领先的权威资讯机构IDC正式发布《IDC Market Presentation&#xff1a;生成式AI推动下的中国网络安全硬件市场现状及技术发展趋势&#xff0c;2024》报告。报告中IDC 评估了众多厂商的安全硬件产品能力&#xff0c;并给出了产品对应的推荐厂商供最终用户参…

04 | 深入浅出索引(上)

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记&#xff01; 索引的常见模型 可以提供查询效率的数据结构有很多&#xff0c;常见的有三种&#xff1a;哈希表、有序数组、搜索数。 哈希表是一种以 key-value 形式存储的数据结构。输入一个 key&#xff0c;通过固定…

强烈推荐java人,2024年大厂面试背这份(八股文+场景题结合)!很管用!

2024 年的行情&#xff0c;和 3~4 年前不同&#xff0c;通过海量简历投递和海量面试找工作的时代已经过去了。 在如今面试机会较少&#xff0c;并且面试难度较大的情况下。 充分做好面试的准备才是快速通过面试最有效的方法&#xff01; 切忌把真实面试当靶场&#xff0c;最…

信息学奥赛初赛天天练-48-CSP-J2020完善程序2-变量交换、冒泡排序、贪心算法、最小区间覆盖

PDF文档公众号回复关键字:20240728 2020 CSP-J 完善程序2 1 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) 最小区间覆盖 给出 n 个区间&#xff0c;第 i 个区间的左右端点是 [ai,bi]。现在要在这些区间中选出若干个&#xff0c;使得区间 [0, m] 被所选区间的…

前端框架 element-plus 发布 2.7.8

更新日志 功能 组件 [级联选择器 (cascader)] 添加持久化属性以提升性能 (#17526 by 0song)[日期选择器 (date-picker)] 类型添加月份参数 (#17342 by Panzer-Jack)[级联选择器 (cascader)] 添加标签效果属性 (#17443 by ntnyq)[加载 (loading)] 补充加载属性 (#17174 by zhixi…