传递给函数时对象中键的打字稿缩小 [英] Typescript narrowing of keys in objects when passed to function

查看:25
本文介绍了传递给函数时对象中键的打字稿缩小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 TypeScript 不对对象的成员应用类型缩小到对象类型本身,以便它可以传递给另一个需要缩小类型的函数?如何在不失去类型安全性的情况下修复/规避此问题?

Why does TypeScript not apply type narrowing on members of objects to the object type itself, such that it can be passed to another function that expects a narrowed type? How can this be fixed/circumvented without loosing typesafety?

最小示例:

type A = { key: string | null};
type B = {key: string};

function func(a: B) {};

const a: A = {key:'abcd'};
if(typeof(a.key)==='string') {
  a.key // has (narrowed) type 'string'
  func(a); // still does not work
}

错误消息是:属性key"的类型不兼容.输入'字符串|null' 不能分配给类型 'string'.

游乐场-链接

推荐答案

这最终是一个 TypeScript 的设计限制.它不在对象的属性上使用类型保护来缩小对象本身,除非在对象是 discriminated union 类型的特殊情况... 就您而言, A 根本不是联合,更不用说是受歧视的联合了.

This is ultimately a design limitation of TypeScript. It does not use type guards on an object's properties to narrow the object itself, except in the particular case where the object is a discriminated union type... and in your case, A isn't a union at all, let alone a discriminated one.

我为您的案例执行此操作的方法是引入 用户定义的类型保护函数,它明确地执行您期望的缩小:您传入一个具有 key 属性的对象,并返回 truefalse 取决于此对象是否是有效的 B:

The way I'd do this for your case is to introduce a user-defined type guard function which explicitly performs the narrowing you expect: you pass in an object with a key property, and return true or false depending on whether or not this object is a valid B:

const isB = (x: { key: any }): x is B => typeof x.key === "string";

然后你使用它:

if (isB(a)) {
  func(a); // okay
}

这(给予或接受函数调用)与您的代码基本相同的逻辑,但编译器现在可以识别您的意图.好的,希望有帮助;祝你好运!

This is (give or take a function call) essentially the same logic as your code, but the compiler recognizes your intent now. Okay, hope that helps; good luck!

链接到代码

这篇关于传递给函数时对象中键的打字稿缩小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆