记录一些自己在ts上费过时间的地方。

(先吐个槽:stackoverflow是真的啥都有,百度是真的没法用)

as断言的兼容性误解,如"a" as "b"这种代码是不会报错的。

interface和type的不一致行为(初遇还以为自己写错类型,一脸懵逼的):

type Type = {
  key: "value"
}
interface Interface {
  key: "value"
}

type 似乎没差别都是true = Type extends Interface ? Type extends Interface ? true : false : false

type 坑点 = {
  [key: string]: 坑点
} | string

type 测试<T> = T extends 坑点 ? true : false
type 这个是true = 测试<Type>
type 这个是false = 测试<Interface>

github上官方有说明,是故意留这么个坑的。说是因为interface可扩展(同名自动合并),所以不便检测。

用泛型实现函数重载的效果时,在函数的实现中,会因泛型不具备具体约束,导致经常需要使用as强制断言。

//差不多这意思,下面的代码懒得实际测了🙃

//fns是个函数索引表,TFns是索引表的const类型
function 重载失败<T extends keyof TFns>(fn:T, params: Parameters<fns[T]>){
    fns[fn](...params)//在实现中联合类型不会缩小,所以会报错
    //错误应该像是 不能将方法1的参数传给方法2 这种
}
//但外部使用时,符合类型的语义也没啥事

扩展运算符并不符合直观感受: [...string[], number]这种类型在使用时是符合阅读时的直觉的(要求数组末尾是number元素),但是[...string[], null, ...object[], number]这种不行,不会按顺序来也不会报错。新版ts加了禁止连续解构的规则,这种类型直接不让写了。

其实这里有解决办法,但是写出来的类型简直没法看(几十行,包含大量extends充当类型的if判断),就不贴了 下面贴代码:

//需要的类型:[...number[], "middle-element", ...boolean[]] 
//上面的写法是无效的,只是示意下面的类型代码是干什么用的(实现上面示意的类型约束)

type Elem = number | boolean | "middle-element";

type Last<T extends any[]> = T extends [infer _]
  ? never
  : T extends [...infer _, infer Tl]
  ? Tl
  : never

type HandleEmpty<T extends any[], Data> = T['length'] extends 0 ? never : Data

type Validation<Params extends any[], Cache extends Elem[] = []> =
  Params extends []
  ? Cache['length'] extends 0
  ? never
  : Cache
  : Params extends [infer Fst, ...infer Rest]
  ? Cache extends []
  ? Fst extends number
  ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>>
  : never
  : Fst extends number
  ? Last<Cache> extends number
  ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>>
  : never
  : Fst extends "middle-element"
  ? Last<Cache> extends number
  ? HandleEmpty<Rest, Validation<Rest, [...Cache, Fst]>>
  : never
  : "middle-element" extends Cache[number]
  ? Fst extends boolean
  ? Validation<Rest, [...Cache, Fst]>
  : never
  : never
  : never

type IsNever<T> = [T] extends [never] ? true : false;

function check<
  Params extends Elem[],
  IsValid extends Validation<Params>
>(...arr: IsNever<IsValid> extends true ? [never] : [...Params]) {
  return arr
}

const 正常 = check(1, 'middle-element', false)
const 报错 = check(false, "middle-element", 2)

进阶操作

对象名重映射:

//{ "new-a":any; "new-b":any }
type 重映射 = {
    [K in "a" | "b" as `new-${K}`]: any
}

联合类型的拆分:用infer关键字可以实现对联合类型的拆分。

//"a1"|"b2"
type 拆分成功<_Keys = keyof { a: 1, b: 2 }> = _Keys extends infer K ?
    `${Extract<K, string>}${{ a: 1, b: 2 }[Extract<K, _Keys>]}`
    : never

//注意:(截止ts4.4.4)直接`keyof Obj extends infer K`无法分割联合类型,原因不明(懒得查😁)。
//结果是"a1"|"a2"|"b1"|"b2"
type 拆分失败 = keyof { a: 1, b: 2 } extends infer K ?
    `${Extract<K, string>}${{ a: 1, b: 2 }[Extract<K, "a" | "b">]}`
    : never

元组类型:

  • 实际(非类型)参数有时候需要通过as const明确定义为元组类型。
  • 元组类型可以通过元组["length"]获取准确的长度,而不是number。
  • 元组类型在通过泛型参数使用时,有时候需要通过加个[]|写成元组 extends []|any[]这种方式来避免被解析为普通的不定长数组类型。

递归类型:用...infer More可以实现对数组类型的递归。

type 转换器<T> = T extends string ? "str" : null
//进去是个[string,number,string],出来就会是["str",null,"str"]
type 递归<
        输入源 extends any[],
        内部的类型缓存 extends any[] = []
    > = 输入源 extends [any, ...infer 剩余元素] ?
        递归<剩余元素, [...内部的类型缓存, 转换器<输入源[0]>]>
        : 输入源

零碎

  • &可以代替extends对type使用,interface除了可以合并同名的类型,其它的没啥差别了。
  • ts具有丰富的内建类型,挑几个例子:
    • ReturnType<函数类型>,获取函数类型的返回值的类型。
    • Uncapitalize<字符串>,将输入的字符串类型的首字母锁定为小写(其它还有首字母大写、全小写、全大写)。

新手建议去官网翻文档。

入了ts坑后,可以没事关注下版本更新带来的新特性(玩法)。

总结

到此这篇关于在TypeScript上费过时间的地方总结的文章就介绍到这了,更多相关ts费时间的地方内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

一些在TypeScript上费过时间的地方总结的更多相关文章

  1. iOS – 开始iOS教程 – 变量之前的下划线?

    这是正确的还是我做错了什么?

  2. Swift开发快速上手系列教程目录-陆续完善,由浅入深

    Swift开发教程一.Swift基础Swift教程01-使用switfc终端命令编译运行swift程序Swift教程02-抓住下一个浪潮之巅Swift教程03-playground剖析swift语言Swift教程04-定义声明变量重要原则Swift教程05-基本数据类型(一)整型浮点型Swift教程06-基本数据类型(二)Bool布尔类型对比Java-boolean,Objc-BOOLSwift教

  3. Swift2.0不深入只浅出入门教程-01-The Basic

    本套视频教程是Swift2.0的入门教程,如果你看过其他的教程,可以不看这套教程,录制这套教程的目的,一个是为了自学,一个是为之后自己的另一套教程打基础。本期教程主要介绍Swift语言的一些基础知识。由于CSDN学院的课程审核还没有通过,所以暂时就放到了百度网盘。

  4. Swift教程-视频拍摄教程

    在此教程中,我们将拍摄一段保存到手机相册的视频。教程运行在iOS8.4和Xcode6.4下。打开Xcode并创建一个newSingleViewApplication,项目名称为IOS8SwiftTakeVideoPlayerTutorial,接着填上你的OrganizationName和OrganizationIdentifier,选择Swift语言,在设备一栏只选择iPhone。ImagePickerController的数据可以是Camera或Movie两种类型。视频的maximum长度设置为10秒。

  5. 详解 SiriKit - SiriKit 教程Part 2

    此文章是SiriKit教程系列的第二篇,建议先去阅读第一篇。处理SiriKit请求为了让集成的Siri更有用,可以使用INSendMessageIntentHandling协议的回调方法增加信息内容。协议有以下可选方法:只要实现这些方法,就可以给SiriKit提供更多信息,例如接收者、内容、小组名字、服务名字或者发送者。后面会详细说明区别,现在先介绍如何使用Siri提供的数据。Siri传入的intent对象包含文字版的消息内容。现在当我们尝试发送消息时,SiriKit就明白必须要提供内容值。

  6. swift 学习资源 - Swift 语言指南

    对于精选项目及文章,可直接访问《Swift项目精选》和《Swift文章精选》。对于Swift开源及跨平台开发的同学,可以关注swift.org教程文章开源项目推荐网站苹果官方Swift:Swift概述、博客以及开发资源。swift.org:开源后独立出来的Swift开源社区。ksm/SwiftInFlux:作者将AppleDeveloperForums上有关Swift特性、缺陷及变更讨论分类汇总并更新到GitHub,具有很好的可读性。从中可以一窥Swift缺陷及未来潜在地变化。近期第一时间出了三本Swif

  7. [译] NSCollectionView 入门教程

    Mac中自带的Finder和Photos就是使用了它:通过一个CollectionView来展示所有的文件和图片。NSCollectionView最早在OSX10.5被推出,它可以非常方便地布局一组具有相同大小的item,并把它们展示在一个可以滑动的ScrollView中。在OSX10.11ElCapitan中,参照iOS上的UICollectionView,NSCollectionView被全面进行了升级。在这个NSCollectionView的入门教程中,你将会创造一个叫SlideMagic的app,

  8. unity3d – Android游戏开发使用统一3D教程

    我是团结3D的新手.我打算用Unity3D开发一个安卓游戏,我已经在网上搜索了Unity3D中的android相关教程,但是找不到一个好的开发人员教我一个应用程序启动,所以大家请建议我一个网站我可以启动.我需要android教程,而不是独立的平台教程.提前致谢.解决方法你可以使用Google或Unity3Dofficialdocumentation.

  9. Arduino和Android的“Hello World”教程

    我当然知道Arduino网站和Android开发者文档,但它们过于复杂……解决方法你问两个问题:我如何编程Arduino?

  10. android – 自定义导航抽屉的涟漪效果

    我正在开发我的第一个应用程序,为它提供新的材料外观.我有点迷失了所以我正在按照一些教程来实现工具栏,导航抽屉等等.我不得不说我正在做它提供兼容前棒棒糖的Android版本,所以我正在使用支持图书馆.我的问题是,我刚刚在本教程之一中实现了导航抽屉,并使用以下库来实现兼容性:我认为代码实现太长了,不能把它放在这里,所以我将提供本教程的链接,我完全按照here说的那样完成.我的问题是,当我从导航抽屉的行

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部