有没有一种方法可以在对象属性析构函数中使用零合并运算符("??")



在ReactJS中,我通常使用这种模式的destructurnig-props(我想这是很习惯的(:

export default function Example({ ExampleProps }) {
const {
content,
title,
date,
featuredImage,
author,
tags,
} = ExampleProps || {};

我可以在销毁时添加默认值,这增加了一些安全性:

export default function Example({ ExampleProps }) {
const {
content = "",
title = "Missing Title",
date = "",
featuredImage = {},
author = {},
tags = [],
} = ExampleProps || {};

但现在我切换到TypeScriptstrict模式,我有一段相当艰难的时间。我的道具是由GraphQl codegen键入的,实际上所有属性都封装在Maybe<T>类型中,所以当展开时,会有类似的actualValue | null | undefined

默认值({ maybeUndefined = ""} = props)可以在值为undefined的情况下保存我,但null的值会通过,所以TS编译器很烦人,我的代码会导致很多:

tags?.nodes?.length // etc…

这让我有点紧张,因为《可选链接的成本》一文(尽管我不知道2021年它的回报率如何(。我还听说CCD_ 7运算符的过度使用被称为";代码气味";。

是否有一种模式,可能利用了??运算符,可以让TS编译器满意,并且可以删除至少一些very?.long?.optional?.chains

我看到了两个可能的选项:

  1. 逐属性执行零合并属性,或

  2. 使用实用程序功能

逐个属性

相当缓慢(我是一个缓慢的开发人员(:

// Default `ExampleProps` here −−−−−−−−−−−−−−−vvvvv
export default function Example({ ExampleProps = {} }) {
// Then do the nullish coalescing per-item
const content = ExampleProps.content ?? "";
const title = ExampleProps.title ?? "Missing Title";
const date = ExampleProps.date ?? "";
const featuredImage = ExampleProps.featuredImage ?? {},
const author = ExampleProps.author ?? {},
const tags = ExampleProps.tags ?? [];
// ...

效用函数

或者,使用以下实用程序函数将null值(编译时和运行时(转换为undefined,这样在对结果进行析构函数时就可以使用析构函数默认值。类型部分相当简单:

type NullToUndefined<Type> = {
[key in keyof Type]: Exclude<Type[key], null>;
}

那么效用函数可能是这样的:

function nullToUndefined<
SourceType extends object,
ResultType = NullToUndefined<SourceType>
>(object: SourceType) {
return Object.fromEntries(
Object.entries(object).map(([key, value]) => [key, value ?? undefined])
) as ResultType;
}

或者像这样(可能在运行时更高效(:

function nullToUndefined<
SourceType extends object,
ResultType = NullToUndefined<SourceType>
>(object: SourceType) {
const source = object as {[key: string]: any};
const result: {[key: string]: any} = {};
for (const key in object) {
if (Object.hasOwn(object, key)) {
result[key] = source[key] ?? undefined;
}
}
return result as ResultType;
}

请注意,Object.hasOwn非常新的,但很容易填充。或者您可以使用Object.prototype.hasOwn.call(object, key)

(在nullToUndefined中的这两种情况下,我对类型断言都有点反复无常。对于这样的小型实用函数,我认为只要输入和输出定义良好,这是一个合理的折衷方案。(

然后:

export default function Example({ ExampleProps }) {
const {
content = "",
title = "Missing Title",
date = "",
featuredImage = {},
author = {},
tags = [],
} = nullToUndefined(ExampleProps || {});
//  ^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−^
// ...

游乐场链接

相关内容

  • 没有找到相关文章

最新更新