一行代码引发的离奇问题,众多大佬纷纷参与点评,最终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会越来越好。

往期文章

相关推荐
kyriewen3 小时前
别再 console.log 了:5 个 Chrome DevTools 调试技巧,用过就回不去了
前端·javascript·面试
IT_陈寒5 小时前
Python搞不定字符串编码?这破玩意坑我两小时!
前端·人工智能·后端
DigitalOcean6 小时前
Laravel 开发者已在 DigitalOcean 上开通超过 10 万台服务器
前端·laravel
星始流年6 小时前
从 Tool 到 Skill——基于 LangChain 的服务端Skill实现
前端·langchain·agent
李惟6 小时前
开源本地通信库,纯客户端 RPC,像聊天一样通信
前端
YAwu117 小时前
深入解析 React 炫彩鼠标跟随标题组件:从坐标定位到动画性能
前端·react.js
GuWenyue7 小时前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
OpenTiny社区7 小时前
🎨 看完 GenUI SDK 源码我悟了!
前端·vue.js·github
叁两7 小时前
前端转型AI Agent该如何学习?(前置篇)
前端·人工智能·node.js
何时梦醒7 小时前
深入理解递归与快速排序 —— 从基础入门到手写实现
前端·javascript