注册
web

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

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


image-20240317131231595.png


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


反应


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


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


复现例子


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


declare function hasOwnPropertyextends 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 BivariantCallbackextends AnyFunction> = {
bivarianceHack(...args: Parameters): ReturnType;
}["bivarianceHack"];
type SetStateAction = T | BivariantCallback<(prevState: T) => T>;

interface StoreState> {
getState(): S;
setStateextends keyof S>(key: K, value: SetStateAction): void;
}

export function useStoreProps<
S
extends State,
P
extends Partial,
K
extends keyof S,
>(
store: Store, 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);
});
}
[k]>

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


const value: P[K] & ({} | null)

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


const value: P[K] & {}

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


提出issue


issue的地址在这


image-20240317141601821.png


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


Typescript之父出手解决


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


function f1extends 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在类型系统中的表现的函数解决了这个问题。


image-20240317152740323.png


至此issue被关闭。


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


总结


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


作者:xinling_any
来源:juejin.cn/post/7347210988260147210

0 个评论

要回复文章请先登录注册