捕获类型安全映射器的Typescript映射函数结果类型

时间:2018-10-04 07:04:43

标签: typescript

我正在尝试围绕JSON映射函数描述强大的类型安全约束。 该函数将一个对象作为第一个参数,并使用作为第二个参数传递的映射函数返回该对象的映射表示。

从消费者的角度来看,像这样的合同:

let mappedResult = mapJson(
    // Standard plain object literal coming, most of the time from serverside, generally described by an interface
    // Let's call this type SRC
    { date: "2018-10-04T00:00:00+0200", date2: 1538604000000, aString: "Hello%20World", idempotentValue: "foo" },
    // Applying some mapping functions to convert input values above to a different type representation. Let's call this type MAPPING.
    // Rules are :
    // - Keys should be a subset of SRC's keys
    // - Values should be functions taking SRC[key] and returning a new type NEW_TYPE[key] we want to capture in order to reference it in mapJson()'s result type
    { date: Date.parse, date2: (ts: number) => new Date(ts), aString: unescape }
); // Result type should be something like {[key in SRC]: RESULT[key] ... and SRC[key] if undefined}
// Expecting to get mappedResult = { date: Date.parse("2018-10-04T00:00:00+0200"), date2: new Date(1538604000000), aString: unescape("Hello%20World"), idempotentValue: "foo" }
// Meaning that expected type would be { date: number, date2: Date, aString: string, idempotentValue: string }

我遇到了多种复杂情况:

  1. 按键捕获映射函数的返回类型
  2. 在结果中使用此捕获的类型...,如果在NEW_TYPE中找不到,则返回SRC类型(类似于并集类型,但不完全是这样)

我尝试了类似的操作,但由于mapJson()结果值类型为any,所以我什至无法1 /工作(我知道2 /在这种情况下不应该工作):

function mapJson<
    SRC extends object,
    // That's a 'capture-only' type definition here, used as a placeholder for mappings' return types
    CAPTURED_TARGET_MAPPINGS_TYPES extends {[ATTR in keyof SRC]?: CAPTURED_TARGET_MAPPINGS_TYPES[ATTR]} ,
    TARGET_MAPPINGS extends {[ATTR in keyof SRC]?: (value: SRC[ATTR], obj?: SRC) => CAPTURED_TARGET_MAPPINGS_TYPES[ATTR]}
>(src: SRC, mappings: TARGET_MAPPINGS): {[ATTR in keyof SRC]: CAPTURED_TARGET_MAPPINGS_TYPES[ATTR]} {

    // implementation here... not the purpose of this question :-)
}

我的目的是真正拥有一个强大的类型安全功能签名(用于输入和输出),我想知道Typescript 3.1当前是否可以处理这种情况。

如果您有空闲时间来帮助您,我将不胜感激:-)

1 个答案:

答案 0 :(得分:0)

我不会将多余的CAPTURED_TARGET_MAPPINGS_TYPES用于映射类型,我只会使用条件类型来获取函数的返回类型(如果未指定类型映射,则使用原始类型,例如{{ 1}})

idempotentValue

这应该可以追溯到2.8,不确定您当前使用的版本。