【发布时间】:2022-01-14 09:45:01
【问题描述】:
type Formula =
| {
fn: (a: number) => number;
arg: number;
}
| {
fn: (a: () => number) => number;
arg: () => number;
};
在此示例中,我如何键入公式,以便 fn 始终接受 arg 作为参数?我仍然需要像 Formula 这样的类型来表示这两种公式,以防我想将它们混合在一个列表中或创建一个可以返回任何一种类型的函数。
formula1.fn(formula1.arg) // should always work.
换句话说:
- 如果
arg是number,则fn应该是(number) => number - 如果
arg是() => number,则fn应该是(() => number) => number - 存在一种涵盖两种类型的公式。
// Just applies formula.fn to formula.arg
const calc = (
formula: Formula
) => formula.fn(formula.arg); // formula.arg fails to type check
/*
Argument of type 'number | (() => number)' is not assignable to parameter of type 'number & (() => number)'.
Type 'number' is not assignable to type 'number & (() => number)'.
Type 'number' is not assignable to type '() => number'.ts(2345)
*/
// Should succeed (fn takes a number and arg is a number)
const num1 = calc({
fn: (a) => a + 1,
arg: 3
})
// Should succeed (fn takes a () => number and arg is a () => number)
const num2 = calc({
fn: (a) => a() + 1,
arg: () => 3
})
// Should fail because arg is a number and fn expects a () => number parameter
const num3 = calc({
fn: (a) => a() + 1,
arg: 4
})
// Should fail because arg is a () => number and fn expects a number parameter
const num4 = calc({
fn: (a) => a + 1,
arg: () => 4
})
// It should be possible to build an array
// containing types of formulas.
const formulas: Formula = [
// plain number formula
{
fn: a => a + 3,
arg: 4
},
// () => number formula
{
fn: a => a() * 2,
arg: () => 11
}
]
const answers = formulas.map(calc)
谢谢!
【问题讨论】:
标签: typescript types typescript-generics