一行代码引发的离奇问题,众多大佬纷纷参与点评,最终Typescript之父出手解决

故事的起因是这样的, 一个前端开发人员(也算是挺有名的,ariakit.org的作者, wrodPress的前维护者)在社交媒体上发了这么一条帖子。

短短几天就有了51.8万次的view。 简单的文案:又是使用 TypeScript 的一天.。表达了对Typescript的又爱又恨😂。在目前的前端市场上,Typescript已经成为标配,ts强大的类型检查机制给我们带来了非常多的好处(代码质量,强大的可维护性,代码即注释),但是其槽点也很多, 很多奇奇怪怪的问题(相信不仅是我一个人这么觉得),繁多的配置项组合,稍不注意就会引起页面爆红,代码量增多和代码组织也会引起一定的负担。但在这些并不能撼动Typescript 在目前前端社区中的地位,在开发项目中一般还是会选择typescript。

反应

话说回到这个帖子上,这个帖子发出来之后迅速引起发酵,被很多大佬转发和引用,下面的评论很多都是wait, what, why happen?类似的语气😂,有很多给出建议,比如换种写法, 重启下Typescript server试试,也有很多开发爱好者希望作者能提供一个例子来复现,他们也想看看是什么问题,看能不能尝试解决这个有趣的例子。

(ps: 在ts中有很多奇怪的东西,特别是在和编辑器配合的时候,有些时候不能判断出来是否是个bug?还是我们代码写的有问题?还是设计如此?还是编辑器的问题?还是版本兼容问题?仅代表个人看法)

复现例子

后来有大佬根据作者提供的信息复现出来了样板例子

ts 复制代码
declare function hasOwnProperty<T extends AnyObject>(
  object: T,
  prop: keyof any,
): prop is keyof T;

type EffectCallback = () => void;

declare const useSafeLayoutEffect: (effect: EffectCallback) => void;

type AnyObject = Record<string, any>;
export type State = AnyObject;

type AnyFunction = (...args: any) => any;
type BivariantCallback<T extends AnyFunction> = {
  bivarianceHack(...args: Parameters<T>): ReturnType<T>;
}["bivarianceHack"];
type SetStateAction<T> = T | BivariantCallback<(prevState: T) => T>;

interface Store<S = State> {
  getState(): S;
  setState<K extends keyof S>(key: K, value: SetStateAction<S[K]>): void;
}

export function useStoreProps<
  S extends State,
  P extends Partial<S>,
  K extends keyof S,
>(store: Store<S>, props: P, key: K) {
  const value = hasOwnProperty(props, key) ? props[key] : undefined;

  useSafeLayoutEffect(() => {
    if (value === undefined) return;
    value;
    // ^?
    if (value === undefined) return; // toggle this to see the magic
    value;
    // ^?
    store.setState(key, value);
  });
}

将鼠标放到倒数第八行上显示value的类型:

ts 复制代码
const value: P[K] & ({} | null)

但是将鼠标放到倒数第五行时显示的value类型:

ts 复制代码
const value: P[K] & {}

真是见了鬼了 。同样的操作复制了一遍,显示的类型却不一样?是的,这很Typescript😏。

提出issue

issue的地址在这

这个提出issue的哥们就是复现样板例子的人,看的出来他应该是个狂热的技术爱好者,执行力也很强,从问作者要出现这种情况的代码仓库可以是否可以公开 ==> 复现样板例子 ==> 给Typescript提出issue(还尝试了自己能不能解决),执行力power👍。

Typescript之父出手解决

在提出issue之后立即就被官方定位是一个bug, 而且Typescript之父还给出了一个简化版可复现的例子:

ts 复制代码
function f1<T extends Record<string, any>, K extends keyof T>(x: T[K] | undefined) {
    if (x === undefined) return;
    x;  // T[K] & ({} | null)
    if (x === undefined) return;
    x;  // T[K] & {}
}

通过上面的例子发现null被意外的消除了。

ahejlsberg(ts之父) 写了一个规范化nullundefined在类型系统中的表现的函数解决了这个问题。

至此issue被关闭。

我们打开palyground的nightly版本,可以发现这个问题被解决, 错误不在显示了。

总结

这是无意间从网上看到,然后从问题追溯到问题被一步步的解决。从帖子中可以看出来现在大部分用Typescript写项目的人又爱又恨的普遍状态。不管你是多菜的菜鸟也能感受到ts给日益庞大的前端项目带来的好处,不管你是多厉害的大牛也是会遇到一些奇怪的错误。随着Typescript的普及,社区中有很多不同的声音,有热爱者,有反对者,也有随波逐流者,但这也代表Typescript在社区中展现的旺盛生命力。质疑也好,热爱也罢,我觉得ts会越来越好。

往期文章

相关推荐
小李小李不讲道理1 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻1 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front2 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰2 小时前
纯flex布局来写瀑布流
前端·javascript·css
chhanz3 小时前
git/github入门基操(终端版)
git·github
一袋米扛几楼984 小时前
【软件安全】什么是XSS(Cross-Site Scripting,跨站脚本)?
前端·安全·xss
向上的车轮4 小时前
Actix Web适合什么类型的Web应用?可以部署 Java 或 .NET 的应用程序?
java·前端·rust·.net
XiaoYu20024 小时前
第1章 核心竞争力和职业规划
前端·面试·程序员
excel4 小时前
🧩 深入浅出讲解:analyzeScriptBindings —— Vue 如何分析 <script> 里的变量绑定
前端
蓝瑟4 小时前
AI时代程序员如何高效提问与开发工作?
前端·ai编程