Ramda 的类型检查助手

type checking helper with Ramda

我想编写一个函数,其规格在下面的代码段中进行了描述,这是我当前的实现。它确实有效。然而,我一直在尝试将它写成 pointfree 并且完全作为 ramda 函数的组合,但找不到解决方案。该问题与 obj => map(key => recordSpec[key](obj[key]) 相关联,我无法以可以无意义地编写整个内容的方式减少它。

我该怎么办?

/** * check that an object : * - does not have any extra properties than the expected ones (strictness) * - that its properties follow the defined specs * Note that if a property is optional, the spec must include that case * @param {Object.<String, Predicate>} recordSpec * @returns {Predicate} * @throws when recordSpec is not an object */ function isStrictRecordOf(recordSpec) { return allPass([ // 1. no extra properties, i.e. all properties in obj are in recordSpec // return true if recordSpec.keys - obj.keys is empty pipe(keys, flip(difference)(keys(recordSpec)), isEmpty), // 2. the properties in recordSpec all pass their corresponding predicate // For each key, execute the corresponding predicate in recordSpec on the // corresponding value in obj pipe(obj => map(key => recordSpec[key](obj[key]), keys(recordSpec)), all(identity)), ] ) }

例如, isStrictRecordOf({a : isNumber, b : isString})({a:1, b:'2'}) -> true isStrictRecordOf({a : isNumber, b : isString})({a:1, b:'2', c:3}) -> false isStrictRecordOf({a : isNumber, b : isString})({a:1, b:2}) -> false

实现此目的的一种方法是使用 R.where,它采用像您的 recordSpec 这样的规范对象,并将每个谓词应用第二个对象的相应键的值。

您的函数将如下所示:

const isStrictRecordOf = recordSpec => allPass([
  pipe(keys, flip(difference)(keys(recordSpec)), isEmpty),
  where(recordSpec)
])