【发布时间】:2018-10-04 16:36:29
【问题描述】:
我试图描述围绕 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 }
我遇到了多种复杂情况:
- 按键捕获映射函数返回类型
- 在结果中使用这个捕获的类型...如果在 NEW_TYPE 中找不到,则使用 SRC 类型(类似于联合类型,但不完全一样)
我尝试过类似的方法,但我什至无法让 1/ 工作(我知道 2/ 在这种情况下不应该工作),因为 mapJson() 结果值类型是 any 类型:
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 目前是否可以处理这种情况。
如果您有空闲时间可以提供帮助,我将不胜感激 :-)
【问题讨论】:
标签: typescript