首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用动态提供的键值对创建一个对象,从而使类型记录的“`exactOptionalPropertyTypes = true` ` check”?

如何使用动态提供的键值对创建一个对象,从而使类型记录的“`exactOptionalPropertyTypes = true` ` check”?
EN

Stack Overflow用户
提问于 2022-01-20 22:34:52
回答 1查看 484关注 0票数 0

类型检查选项套件中的介绍 exactOptionalPropertyTypes

在JavaScript中,读取对象上缺少的属性会产生未定义的值。还可以使用未定义值的实际属性。JavaScript中的许多代码倾向于以同样的方式处理这些情况,因此最初TypeScript只是将每个可选属性解释为用户在类型中编写了未定义的内容。例如, 接口人{名称:字符串,年龄?:数字;} 被认为相当于 接口人{名称:字符串,年龄?:数字,未定义;} 这意味着用户可以显式地编写未定义的内容来代替年龄。 const p: Person ={ name:"Daniel",age: undefined,//这在默认情况下是可以的。}; 因此,默认情况下,TypeScript不区分值未定义的当前属性和缺少的属性。虽然大多数情况下这是可行的,但并非JavaScript中的所有代码都有相同的假设。函数和操作符,如Object.assign、Object.keys、对象扩展({ ...obj })和for-in循环的行为不同,取决于对象上是否存在属性。在我们的Person示例中,如果在age属性的存在很重要的上下文中观察到age属性,这可能会导致运行时错误。在TypeScript 4.4中,新标志 //与'exactOptionalPropertyTypes‘在: const : Person ={ name:"Daniel",年龄:未定义,//错误!未定义的不是一个数字}; 这个标志不是--严格的家庭的一部分,如果你想要这样做的话,需要明确地打开它。它还要求启用我们将对DefinitelyTyped和其他定义进行更新,以尽可能简单地进行转换,但您可能会遇到一些摩擦,这取决于代码的结构。

如果启用此功能标志,则我的代码

代码语言:javascript
运行
复制
function f(input: OptionsInterface): void {
  const target: PacketInterface = {
    cmd: 'connect',
    clientId: input.clientId,
    protocolVersion: input.protocolVersion,
  };
  console.log(target);
};

给出错误:

代码语言:javascript
运行
复制
Type '{ cmd: "connect"; clientId: string; protocolVersion: 4 | 5 | 3 | undefined }' is not assignable to type 'PacketInterface' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Types of property 'protocolVersion' are incompatible.
    Type '4 | 5 | 3 | undefined' is not assignable to type '4 | 5 | 3'.

“目标”接口是PacketInterface:

代码语言:javascript
运行
复制
export interface PacketInterface {
  cmd: 'connect'
  clientId: string
  protocolVersion?: 4 | 5 | 3
}

所提供的对象的接口是``PacketInterface‘的一个超集:

代码语言:javascript
运行
复制
export interface OptionsInterface {
  cmd: 'connect'
  clientId: string
  protocolVersion?: 4 | 5 | 3
  clean?: boolean
  keepalive?: number
  username?: string
  password?: Buffer
}

我创建了MCVE来演示这一点:TS游乐场MCVE

我有一个超集'options‘对象,它为基于依赖关系的接口的子集'packet’对象提供值。在'packet‘接口中,可选值使用?:,这意味着如果我提供undefined作为值,TypeScript现在会抱怨。

虽然预计会出现错误,但解决方案尚不清楚。当前无法更新依赖项的类型。我只需禁用exactOptionalPropertyTypes功能标志就可以消除错误,但这会移除类型检查的级别。启用此功能标志时,如何使用未定义的值创建对象?类型强制?以某种方式使用接口来检查options对象中的值?我不想手动检查“options”对象中的每个值,以便在将其添加到我正在创建的“packet”类型对象之前查看它是否存在。

EN

回答 1

Stack Overflow用户

发布于 2022-01-20 23:54:54

您必须拥有未定义的密钥。因此,您可以使用三元或扩展运算符:

代码语言:javascript
运行
复制
interface foo {
    x?: string;
    y?: number;
    z?: number;
}

interface bar {
    x?: string;
}

function f(input: foo): void {
    const zoom: bar = input.x ? { 'x': input.x } : {};
    /// or
    const zoom: bar = { ...input }

    console.log(zoom);
};

游乐场

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70794241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档