gpt4 book ai didi

javascript - 使用 Sanctuary 从具有特定 RecordType 的对象中选取字段

转载 作者:行者123 更新时间:2023-11-29 10:04:33 31 4
gpt4 key购买 nike

我有一个对象,其选项对应于以下记录类型:

const AwsRegionsEnum = $.EnumType(
'AWS/Regions',
'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html',
[
'us-east-1',
'us-east-2',
'us-west-1',
'us-west-2',
'ca-central-1',
'eu-west-1',
'eu-central-1',
'eu-west-2',
'ap-northeast-1',
'ap-northeast-2',
'ap-southeast-1',
'ap-southeast-2',
'ap-south-1',
'sa-east-1',
]
);
const Credentials = $.RecordType({
accessKeyId: $.String,
secretAccessKey: $.String,
region: AwsRegionsEnum,
});

const PullOpts = $.RecordType({
waitTimeSeconds: S.MaybeType($.Number),
maxNumberOfMessages: S.MaybeType($.Number),
credentials: Credentials,
});

我想创建一个函数,从类似 R.pick 的记录中选择选项来自 ramda 图书馆。但我想输入列表字段进行挑选。该列表只能包含对 PullOpts 类型的记录有效的字段.

函数的预期行为:

// pickOpts :: List(<some_type_for_validate_options>) -> PullOpts -> <constructed_type_for_return>
const pickOpts = (pickingOpts, allOpts) => {};

总结:

  1. 我如何正确编写我的函数参数类型( <some_type_for_validate_options><constructed_type_for_return> )?

  2. 我如何使用避难所函数编写函数体作曲?

感谢您的帮助:)

最佳答案

在 Sanctuary 中,通常不需要从记录中挑选某些字段。考虑这个模块:

const $ = require('sanctuary-def');
const types = require('./types');

const def = $.create({checkTypes: true, env: $.env});

// User :: Type
const User = $.RecordType({
id: types.UUID,
username: $.NonEmpty($.String),
email: types.Email,
});

// MinimalUser :: Type
const MinimalUser = $.RecordType({
id: types.UUID,
username: $.NonEmpty($.String),
});

// toMinimalUser :: User -> MinimalUser
const toMinimalUser = def(
'toMinimalUser',
{},
[User, MinimalUser],
user => ???
);

代替 ??? 的实现应该是什么。答案可能令人惊讶:我们只是返回 user。这是因为 User 类型的每个成员也是 MinimalUser 类型的成员。允许记录包含附加字段。这使得可以定义类型为 id::{ id::UUID } -> UUID 的函数,这些函数不限于特定类型(User发票,或其他)。

因此,toMinimalUser 可能是不必要的。由于 User 类型的每个成员也是 MinimalUser 类型的成员,我们可以传递一个 User/MinimalUser 到需要 MinimalUser 的函数。

虽然类型系统不会要求我们“剥离”字段,但出于隐私原因我们可能希望这样做。考虑 toJson::User -> String。如果我们从 User 值构建 API 响应,我们可能会出于隐私原因排除 email 字段。在这种情况下,我会建议这个实现:

//    toJson :: User -> String
const toJson = def(
'toJson',
{},
[User, $.String],
({id, username}) => JSON.stringify({id, username})
);

这比等效的 R.pick 更冗长,但这是我们必须以比 JavaScript 要求的更规范的方式处理记录的代价。

我可以想象有一天我们会在 Sanctuary 中添加这样的功能:

S.pick :: Set String -> StrMap a -> StrMap a

不过,我无法想象在任意记录上运行类似的函数,因为我们将被迫使用松散类型,例如 Set String -> Object -> Object。在处理 Sanctuary 中的记录时,我更喜欢编写稍微冗长但提供更强保证的代码。

关于javascript - 使用 Sanctuary 从具有特定 RecordType 的对象中选取字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46587410/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com