在使用类型进行函数式编程时,通常可以将应用程序中的类型限制为提供的输入值。
但是,我不知道如何用TypeScript来实现这一点,并使用映射键的可能值。
请考虑以下几点:
const match = <T, V, R>(p : (x : V) => T, ... c : Array< [T, (x : V) => R] >) : (x : V) => R => {
const cases = new Map(c);
return (x : any) => cases.get(p(x))(x);
}更具人类可读性的格式:
const match = <Row, Value, ReturnType>(p : (x : Value) => Row, ...c : Array< [Row, (x : Value) => ReturnType] >) : (x : Value) => ReturnType => {
const cases = new Map(c);
return x => cases.get(p(x))(x);
}但是,这种表示法有一个问题,因为它实际上并不是要做什么:
match(x => Math.random() > 0.5 ? "foo" : "bar", ["baz", x => x])在足够高级的输入系统中,这应该是一个错误,但是在TypeScript中,它没有检测到"foo“或"bar”值不是任何期望值,实际上会导致代码抛出。
一个更深入的例子:
const validDouble = match( x => x * 2,
[4, x => "four"],
[6, x => "six"]
)
validDouble(4) // TS ERROR: 8 is not a valid value for Type ROW (4 | 6)
validDouble(2) // "four", no TS Error我知道我不能强制rest参数为数组的强制值(不过,我可以将其包装在强制数组中,并需要开发人员提供额外的字符),但我很好奇是否有一种方法可以强制执行行中的值与谓词函数中的输出值相匹配?
编辑:是的,我知道这会抛出一个不匹配的输入。该逻辑很容易用条件符插入或尝试捕捉并将其转换为matchMaybe,但是这个示例被简化了,因为这对TypeScript中可用的类型系统没有影响或暗示。
发布于 2018-12-31 10:50:37
好的,这是一个固定的函数(可能需要一些整理和改进)。
const match = <
Row extends string | number,
Value,
ReturnType,
V extends (x: Value) => ReturnType,
C extends [...[Row, V][]],
>
(
predicate: (x: Value) => Row,
...c: C & [...[Row, V][]]
): (x: Value) => ReturnType => {
const cases = new Map<Row, V>(c);
return x =>
// put a runtime check below instead of asserting
// non-undefined value with `!`
cases.get(predicate(x))!(x)
}
match(x => 'baz', ["baz", (x: any) => x]) // ok
match(x => 'qwe', ["baz", (x: any) => x]) // err
match(x => 'qwe', ["baz", (x: any) => x], ["qwe", (x: any) => x]) //okx]) // ok match(x => 'qwe', ["baz", (x: any) => x]) // err match(x => 'qwe', ["baz", (x: any) => x], ["qwe", (x: any) => x]) //ok // number keys: match(x => 1, [1, (x: any) => x]) // ok match(x => 2, [1, (x: any) => x]) // err match(x => 2, [1, (x: any) => x], [2, (x: any) => x]) //ok">游乐场
第一个问题是rest参数应该是元组。第二个问题是正确放置类型参数,以便所有的推断都正确。
复杂类型的打字是很难的。我觉得缺乏关于类型参数的文档,因此我总是对它们感到不自信(我认为其他人也一样)。
https://stackoverflow.com/questions/53985022
复制相似问题