首页
学习
活动
专区
圈层
工具
发布

奇怪的Typescript返回类型

TypeScript 返回类型详解

基础概念

TypeScript 是一种静态类型检查的 JavaScript 超集,其返回类型系统是类型系统的重要组成部分。返回类型定义了函数或方法执行后返回值的类型。

常见的"奇怪"返回类型情况及原因

1. 联合返回类型

代码语言:txt
复制
function getValue(id: number): string | number {
  if (id > 0) {
    return "positive";
  } else {
    return 0;
  }
}

原因:函数可能根据条件返回不同类型的值,TypeScript 会推断出联合类型。

2. never 返回类型

代码语言:txt
复制
function throwError(message: string): never {
  throw new Error(message);
}

原因:函数永远不会正常返回(总是抛出异常或无限循环),返回类型为 never

3. void 与 undefined 的区别

代码语言:txt
复制
function noReturn(): void {
  console.log("No return");
}

原因void 表示函数没有返回值,而 undefined 表示函数显式返回 undefined

4. 类型推断导致的意外返回类型

代码语言:txt
复制
function processArray(arr: number[]) {
  return arr.map(num => num > 0 ? "positive" : "negative");
}
// 返回类型被推断为 string[]

原因:TypeScript 根据内部逻辑自动推断返回类型,可能与预期不符。

5. 泛型返回类型

代码语言:txt
复制
function identity<T>(arg: T): T {
  return arg;
}

原因:泛型函数会根据输入类型决定返回类型。

解决方案

  1. 显式声明返回类型:避免类型推断带来的意外
代码语言:txt
复制
function getUser(id: number): User | null {
  // ...
}
  1. 使用类型断言:当你知道比编译器更多信息时
代码语言:txt
复制
function getLength(obj: any): number {
  return (obj as string).length;
}
  1. 处理联合类型:使用类型守卫缩小类型范围
代码语言:txt
复制
function printId(id: string | number) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id.toFixed(2));
  }
}
  1. 使用函数重载:为不同参数类型定义不同的返回类型
代码语言:txt
复制
function getDate(timestamp: number): Date;
function getDate(dateStr: string): Date;
function getDate(value: number | string): Date {
  if (typeof value === "number") {
    return new Date(value);
  } else {
    return new Date(value);
  }
}

最佳实践

  1. 尽量显式声明函数返回类型,提高代码可读性
  2. 对于复杂逻辑,使用类型别名或接口定义返回类型
  3. 使用 unknown 代替 any 作为不确定类型的返回类型
  4. 利用 TypeScript 的类型推断能力,但不要过度依赖
  5. 对于异步函数,使用 Promise<T> 明确返回的 Promise 类型

通过理解这些"奇怪"的返回类型行为,可以更好地利用 TypeScript 的类型系统,编写更健壮、可维护的代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • TypeScript函数的类型

    { return x+y; }; 这是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 mySum,是通过赋值操作进行类型推论而推断出来的。...{ return x+y; }; 注意不要混淆了 TypeScript 中的 => 和 ES6 中的 =>。...在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。...==-1; } 采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。...在编辑器的代码提示中,可以正确的看到前两个提示。 注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

    2.6K30

    TypeScript中那几个奇怪的知识点

    写在开头 我写了一年多TypeScript,总结了以下几个点,希望可以帮到大家 如果感觉写得不错,记得来个关注/在看 比较容易遇到的问题 给一个对象添加属性 interface Obj { a: string...这里用了两次泛型,先定义好返回的data数据,再用泛型方式传入,组装好返回的整个返回数据接口(包含code,result,data)。...: 1.使用data作为泛型,传入 2.组装成{code,result,data}这种类型接口 3.将第二步的组装后类型作为泛型传入get方法中 4.返回一个Promise风格的Promise数据 这样做的意义,提取可变的数据类型data,让TS推断出这个接口返回的数据是怎么样的。...减少不必要的重复代码,即每次接口调取都会返回的数据格式类型:code和result 相信你通过这段代码和文字,能真正理解TS的泛型如何用,什么地方使用,以及使用的意义了。

    1.2K10

    TypeScript类型守卫

    因为类型断言还是需要借助类型守卫的,类型守卫主要是用来判断未知类型是不是所需要的类型。...typeof只能识别以下类型:BooleanStringUndefinedFunctionNumberBigintSymbol写法:typeof a,a是变量(基本数据类型)奇怪为什么typeof不能识别...instanceof不能检测原始值类型的值,但是原始值对应的对象格式实例则可以检测。具体instanceof是怎么做类型守卫的呢?写法:a instanceof b,a是参数,b是一般都是接口类型。...这种写法称作类型谓词,使用类型谓词的函数称为类型谓词函数,该函数的返回值必须的boolean类型。...(1)函数参数形式函数中的参数类型为多个类型,通过is关键字自定义类型,将函数参数精确到某种类型,然后再执行相应的逻辑。

    81130

    【TypeScript】类型声明

    当我们使用TypeScript编写代码时,类型声明是非常重要的,它帮助我们定义变量、函数、类等的类型,从而提供更好的代码提示、类型检查和代码可读性。...以下是关于TypeScript类型声明的详细内容:基本类型声明在TypeScript中,我们可以使用以下关键字来声明基本类型:let num: number = 42;let str: string =...(Type Assertion)类型断言允许我们手动指定变量的类型,并告诉TypeScript编译器我们知道更多关于变量的类型信息。...: number; readonly id: number;}以上是关于TypeScript类型声明的一些重要内容。通过合理使用类型声明,我们可以增强代码的可读性、类型安全性和可维护性。...类型声明是TypeScript的核心特性之一,可以帮助我们构建更健壮的代码和应用程序。我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

    59120

    TypeScript never 类型

    它用于表示不返回值的函数的返回类型:例如,永远循环的函数,始终抛出异常信号的函数等。 因为底部类型被用于表示不会正常的返回,一般没有返回值。...了解完底部类型的概念后,下面我们开始来介绍 TypeScript 中对应的底部类型 —— never 类型。...二、never 类型 在 TypeScript 中,never 类型表示的是那些永不存在的值的类型。...never = (() => { throw new Error('TypeScript never'); })(); 另外,对于死循环的函数或执行时总会抛出异常的函数来说,函数对应的返回值类型也是...在这些情况下,我们通常忽略返回值。在 TypeScript 中这些函数的返回类型被推断为 void。 具有 never 返回类型的函数永不返回。它也不返回 undefined。

    4.5K10

    TypeScript 基础类型

    TypeScript 基础类型 TypeScript 包含的数据类型如下表: 数据类型 关键字 描述 任意类型 any 声明为 any 的变量可以赋予任意类型的值。...---- Any 类型 任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型,它常用于以下三种情况。...null是一个只有一个值的特殊类型。表示一个空对象引用。 用 typeof 检测 null 返回是 object。...而在TypeScript中启用严格的空校验(--strictNullChecks)特性,就可以使得null 和 undefined 只能被赋值给 void 或本身对应的类型,示例代码如下: // 启用...')})(); // 运行正确,never 类型可以赋值给 数字类型 y = (()=>{ throw new Error('exception')})(); // 返回值为 never 的函数可以是抛出异常的情况

    86410

    TypeScript 元组类型

    阅读须知:本文示例的运行环境是 TypeScript 官网的 Playground,对应的编译器版本是 v3.8.3。...在 JavaScript 中是没有元组的,元组是 TypeScript 中特有的类型,其工作方式类似于数组。 元组可用于定义具有有限数量的未命名属性的类型。每个属性都有一个关联的类型。...,如果出现类型不匹配的话,比如: tupleType = [true, "Semlinker"] 此时,TypeScript 编译器会提示以下错误信息: [0]: Type 'true' is not...针对这种情形,在 TypeScript 中就可以利用元组类型可选元素的特性来定义一个元组类型的坐标点,具体实现如下: type Point = [number, number?, number?]...六、只读的元组类型 TypeScript 3.4 还引入了对只读元组的新支持。我们可以为任何元组类型加上 readonly 关键字前缀,以使其成为只读元组。

    1.8K20

    TypeScript: 常用的高级类型

    ,枚举类型是真实运行的代码,因此枚举类型是真实存在的对象,而并非仅仅只是简单的类型约束。...可问题在于touch的事件对象与mouse的事件对象是不一样的。那么我们在兼容了这两种事件的回调中,如何去描述该回调的事件对象呢? 通常使用 & 符号来解决这样的常见,将两种类型合并为一种类型。...per: string | string[] 我们在代码编写时,希望能够自动提示对应的api,typescript则不知道应该如何处理这种情况。...这种处理,就叫做类型保护。 5 索引类型 我们可以使用 keyof 来获取一个对象中的key对应的具体值。...我们在实践场景中,还有更多更复杂的组合,这些经验很难通过技术文章获取到,需要在实践中慢慢体会。除此之外,typescript官方文档中,还有一些重要的东西需要去深入学习。

    2.1K10

    TypeScript 中的高级类型

    一、是什么 在 TypeScript 中,除了基本类型如 string、number、boolean 之外,还存在一系列高级类型。...这些高级类型是 TypeScript 为了增加语言灵活性和应对复杂开发场景而提供的一些语言特性。...二、有哪些 以下是一些常见的高级类型及其应用: 交叉类型 交叉类型通过 & 操作符将多个类型合并为一个类型,新类型包含了所有合并类型的特性。...never : T; 三、总结 TypeScript 的高级类型为开发者提供了强大的工具来处理复杂的类型关系和场景。掌握这些高级类型是深入理解和有效使用 TypeScript 的关键。...随着 TypeScript 版本的不断更新,新的特性也在不断加入,因此持续学习和实践是必要的。

    83710

    TypeScript交叉类型&联合类型

    &合并成新的类型吗?...这肯定是不行的,原子类型进行合并是没有任何意义,因为它们合并后的类型是never,比如string&number,这肯定是错误的,因为不可能有既满足字符串又满足数字类型。...,如下图所示:3.2 键的类型是对象类型A、B、C三个类型都有相同的键inner,但是键的数据类型不同,分别是D、E、F,此时A&B&C会将inner键的类型进行合并,其实是D、E、F的交叉类型。...,当键的类型是不同的字面量类型,则交叉后类型为never类型。...二、联合类型(Union types)联合类型和交叉类型比较相似,联合类型通过|符号连接多个类型从而生成新的类型。它主要是取多个类型的交集,即多个类型共有的类型才是联合类型最终的类型。

    1.3K10

    TypeScript函数类型

    # 声明式类型函数 通过如下代码我们实现了一个返回值为number类型的方法,同时我们也对返回值和参数进行了约束 ``` function funcType(name:string,age:number...):number{ return age; } var ageNum:number=funcType("张三",18) ``` 如果说在我们参数不确定的情况下我们可以通过如下代码进行创建...对方法进行添加默认值 ``` function funcType2(name:string="张三",age:number=18):number{ return age; } ``` # 表达式类型函数...``` var funcType3=function(name:string,age:number):numbe { return age; } ``` 如上代码片段是我们之前创建的函数...通过如下代码我们可以实现一个联合类型函数,当然这可以采用重载的方式 当我们的参数是number类型时我们的返回值是number类型,当我们的参数是string类型时我们的返回值是string类型,这一块具体在我们实际业务中可以根据实际需求进行相应修改

    99020

    TypeScript 类型系统

    针对 JavaScript 上面的问题,聪明的同学就想那我们就给 JavaScript 加个类型吧,和 Java 一样,能够对变量的类型进行定义,这个想法就是 TypeScript 的类型系统, 在很大程度上弥补了...从 TypeScript 的名字就可以看出来,「类型」是其最核心的特性,TypeScript 也主要致力于解决 JavaScript 的类型混乱问题。...TypeScript 是静态类型 类型系统按照「类型检查的时机」来分类,可以分为下面 2 种 动态类型 静态类型 动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。...foo.split(' '); // Property 'split' does not exist on type 'number'. // 编译时会报错(数字没有 split 方法),无法通过编译 你可能会奇怪...大部分 JavaScript 代码都只需要经过少量的修改(或者完全不用修改)就变成 TypeScript 代码,这得益于 TypeScript 强大的[类型推论][],即使不去手动声明变量 foo 的类型

    97800

    TypeScript类型声明

    前言本文主要讲解TypeScript的基本数据结构,主要包括JS基本数据类型以及TS特有的数据类型。...数组中数据的位置、类型以及个数必须要和声明的类型、声明类型的位置、声明类型的个数保持一致,否则就会报错。...,强制让ts编译器相信我们在做什么操作六、void(空类型)声明对象类型为void时返回为空值function func(): void { }声明一个变量为void 时只能将它赋值为 undefined...和 null,因此在定义函数的返回值为void时,也可return undefined/nulllet voidValue1: void = undefined;let voidValue2: void...即使any类型也不可以赋值给never类型。返回类型为never的函数中,其终点必须是不可执行的,例如函数过程中抛出了错误或者存在死循环。

    75730
    领券