我正在尝试创建严格的过滤接口:
type Filter<I, O extends I = I> = (value: I) => I extends O ? boolean : false
通过写这一行,我想为一个函数定义一个类型约束:
1.接收I
类型的值
1.如果值不是预期类型的,则返回false
(I extends O
不是true
)
1.如果value是的期望类型并且匹配filter,则返回true | false
但是Typescript忽略条件返回类型:
type MessageA = { type: 'A' }
type MessageB = { type: 'B' }
type Message = MessageA | MessageB
const filter: Filter<Message, MessageA> = ({ type }) => type === 'A'
const inputMessage: Message = { type: 'B' }
if (filter(inputMessage)) {
// the following line produces error
const message: MessageA = inputMessage
// because according to TS compiler
// inputMessage is still `MessageA | MessageB`
}
逻辑上,如果inputMessage
的类型为MessageA
,则filter(inputMessage)
可能产生true
。
我想了解 “它是可以实现的吗?” 和 “如何正确地写它?” 如果是。
我不受typescript版本的限制,目前安装的是最新的(目前)Typescript 3.9.5。我使用的是VSCode 1.46,是否有任何区别。
2条答案
按热度按时间vddsk6oq1#
方案一
你可以试试这个:
但是您仍然需要显式定义返回类型(
: message is MessageA
)。方案二
这一个更复杂,但它使你的类型守卫(细化)类型安全。
为类型保护创建一个工厂,如下所示:
使用方法:
例如,
fp-ts
就使用了这种方法。cwtwac6a2#
通过使用Array.flatMap,您可以过滤值和类型,请参阅: