首页 > 其他分享 >TS中特殊类型-any、unknown、never和extends继承约束、keyof的使用

TS中特殊类型-any、unknown、never和extends继承约束、keyof的使用

时间:2024-08-20 17:49:05浏览次数:3  
标签:unknown never number TS keyof 类型 any

一、any

any类型是没有任何限制的,一旦变量设置为any等于是把类型检查关闭了,TS不会去进行校验,
个人认为既然使用了TS,尽可能还是不要使用any,除非是为了把js项目快速过渡到TS项目,把复杂的类型先用any定义,让项目能够快速启动,但是建议后续还是需要把any重写成对应的类型

二、unknown

unknown类型是TypeScript 3.0引入的,被称作安全的any。

unknown类型是安全的,虽然任何值都可以赋给unknown,
但是我们在使用unknown时如果没有进行类型断言或基于控制流的类型细化时unknown不可以赋值给其它类型(除了unknown和any外)
同理,在unknown没有被断言或细化到一个确切类型之前,是不允许在其上进行任何操作的。

/* 可以把任何值赋值给unknown,但在使用时需要断言确定类型:as、typeof 等等 */

let anyName: any = "我是任何呀";

let unknownName: unknown = "我不知道呀";

let myName: string;
myName = anyName; // any赋值给其他类型,可以正常编译
// myName = unknownName; // unknown在没有断言前,赋值给其他类型,编译报错
myName = unknownName as string; // unknown在这里断言为string,可以赋值给string,正常编译


let unknownNum: unknown;
unknownNum = "123"; // 没有使用前,定义为string,正常编译
unknownNum = 456; // 没有使用前,定义为number,正常编译

let myNum: number;
// myNum = unknownNum + 20; // 编译报错,因为unknown没有断言,TS不知道这是什么类型
myNum = (unknownNum as number) + 20; // 编译正常,unknown断言为number,可以进行加法



// 即使是明确定义了一个对象,但是类型为unknown时,在没有断言前还是不能使用对象的方法或属性
let obj: unknown = { test: '测试属性' };
// console.log(obj.test); // 报错,因为unknown没有断言,TS不知道这是什么类型,不允许操作

// 定义一个类型
interface MyObject {
  test: string;
}

function printUnknown(unknownObj) {
  unknownObj as MyObject
  console.log(unknownObj.test);
}
printUnknown(obj);

 

三、never

‌在‌TypeScript中,‌never类型表示那些永不存在的值的类型。它通常用于表示不可到达的代码分支或抛出异常的函数。‌

never类型表示那些永远不会发生的类型

例如

当一个函数总是抛出异常或进入无限循环: while(true) {}

或者总是会抛出异常: function foo() { throw new Error('Not Implemented') }返回类型就是never.

never类型的应用场景:

  • 主要用来进行编译时的全面的检查,例如你函数里面的 if else if else 分支,是否已经穷尽了所有可能
  • 进行类型校验
/* 只有never类型本身可以赋值给never类型 */

type reqType = "get" | "post";

function req(method: reqType) {
  if (method === "get") {
    console.log("GET 请求");
  } else if (method === "post") {
    console.log("POST 请求");
  } else {
    // 这里never代表我们已经把所有分支情况都处理了,如果reqType还有一个类型是 'put' 那么这就会报错
    const rejectMethod: never = method;
  }
}
/* 校验参数类型 */

function countNum<T>(n: T extends number ? T : never) {
  return n;
}
// 这里可以判断入参是否为number,如果不是,那么T就是never,赋值给never就会报错
countNum(1); // 编译成功
countNum("a"); // 编译报错

 

四、extends关键字既可以用作类继承,也可以用作泛型约束。

类继承中,extends用于表示类之间的继承关系:

class Animal {
  jiao(hour: number) {
    console.log(`Animal叫了这么久${hour}h.`);
  }
}
 
class Dog extends Animal {
  fei() {
    console.log('wangwang!');
  }
}

泛型约束中,extends用于为泛型变量指定类型约束:

function howLong<T extends { length: number }>(arg: T) {
  console.log(arg.length);
}
howLong<string>('hello'); // 5
/* 这里T被约束为具有length属性的类型,这意味着传给howLong的参数arg必须有一个length属性,且其类型为数字。
这里extends更像是一个判断条件,用于确保泛型参数类型符合特定的约束。*/

 

五、keyof

keyof TT 类型的键集

/* keyof T 是 T 类型的键集 */

interface Home {
  addr: string;
  height: string;
}

type h = keyof Home; // 这里 h 就等于 "addr" || "height"


/* 使用 keyof 进行映射类型,需要注意的是映射类型只能在类型别名(type)中使用,不能在接口中使用 */

type K = "a" | "b";
type V1 = { a: number; b: number }

// 上面的写法可以用keyof简化
type V2 = { [key in keyof K]: number }

 

标签:unknown,never,number,TS,keyof,类型,any
From: https://www.cnblogs.com/Zzbj/p/18369955

相关文章

  • ArkUI ARKTS 鸿蒙开发 装饰器
    @State 定义一个变量,可用于本页面的双向绑定 @Prop 定义一个接收参数的变量,随着父组件变化而变化,子组件更改的值会被父组件覆盖(不会更改父组件的值) @Link 定义一个变量,不允许定义值,需要通过父组件传入,可以做到父子组件双向绑定 @Provide装饰器和@Consume装饰器 ......
  • ArkUI ARKTS 鸿蒙开发 @BuilderParam
     @BuilderParam 可以理解成一个html页面的占位符,也可以理解成后端的委托,委托是根据委托的要求传入什么它就执行什么,这个是根据它的要求传入什么就渲染什么1.子页面定义变量      @ComponentexportstructProductItem{@PropProduct:ProductDto;@BuilderP......
  • OI Memory: No Regrets
    其实感觉没什么可以写的啊。我从小学四年级开始接触OI,最开始是在培训机构里学了一年半。刚起步的时候当然是学得很快的,到进入初中的时候,已经差不多把基础算法学完了。五年级的时候,我参加了ZL的提前招。那时这所学校已经在MO上颇有名气,同时也开始在OI方面崭露头角。经过一......
  • 一个AI原生数据应用数据库开发框架,专为数据3.0时代设计,支持私域问答、多数据源交互、
    前言在数字化转型的浪潮中,企业在数据处理和分析方面面临着巨大的挑战。传统软件往往存在复杂的数据库交互、低效的数据整合流程以及缺乏智能化数据分析能力等痛点。这些问题不仅拖慢了企业决策的步伐,也限制了创新的发展。因此,急需一款能够简化数据库交互、智能化数据处理的软......
  • [Web Component] using `part` to allow applying styling from outside the shadow D
    Let'ssaywehaveawebcomponent: import{getProductById}from"../services/Menu.js";import{addToCart}from"../services/Order.js";exportdefaultclassDetailsPageextendsHTMLElement{constructor(){super();......
  • 创建uni-app项目(vue3+ts+vite)
     npxdegitdcloudio/uni-preset-vue#vite-tsm-uni-demo1跳转到对应目录,装包,运行cdm-uni-demo1yarnyarndev:h5tsconfig.json:{"extends":"@vue/tsconfig/tsconfig.json","compilerOptions":{"ignoreDeprecations&quo......
  • CTS2022
    D1T1普罗霍洛夫卡考虑扫描线,那么问题就变成了区间\(+1\),区间历史异或和问题。我们先单独考虑一个数的情况,如果在\(j\)时刻,\(b_i\)增加了\(1\),发现对于后面的所有询问时刻\(j'\),如果\(j\)和\(j'\)的奇偶性相同,那么就会产生\(b_i\oplus(b_i+1)\)的贡献。而由于初始......
  • mavn 执行 junit 单元测试的结果为 Tests run: 0, Failures: 0, Errors: 0, Skipped:
    mavn执行junit单元测试的结果为Testsrun:0,Failures:0,Errors:0,Skipped:0  [INFO]---surefire:3.2.5:test(default-test)@joyupx-trade---[INFO]Usingautodetectedproviderorg.apache.maven.surefire.junitplatform.JUnitPlatformProvider[INFO][INF......
  • 推荐一个开源且免费商用的后台开发框架,基于Bootstrap 的极速版,高效便捷(带私活源码)
     前言在当前的软件开发领域,后台管理系统的开发面临着诸多挑战,如权限管理复杂、开发效率低下、前端界面不统一等。开发者们迫切需要一种能够快速构建、易于扩展、界面美观且具备强大功能的后台管理框架。介绍FastAdmin,一个开源且免费商用的后台开发框架,以其极速的开发体验......
  • Echarts鼠标控制滚动以及自动滚动
    Echarts提供了鼠标控制滚动以及自动滚动的功能。对于鼠标控制滚动,可以使用Echarts的toolbox组件来实现。首先需要在option中配置toolbox组件:option={toolbox:{feature:{dataZoom:{yAxisIndex:'none'//鼠标控制滚动时只......