TS & Vue3: 防止使用 @ts-ignore,因为类型 ‘boolean’ 无法赋值给类型 ‘never’。

huangapple go评论78阅读模式
英文:

TS & Vue3: Prevent using @ts-ignore for Type 'boolean' is not assignable to type 'never'

问题

请问大家好,有人可以帮我解决一个关于接口的打字错误吗?这个问题让我很烦恼,我不确定如何在不使用@ts-ignore的情况下避免这个错误。

这是我的函数:

function proceed() {
  // @ts-ignore
  let mockOptions: MockOptions = {};
  Object.keys(models).forEach((modelKey) => {
    const _modelKey = modelKey as keyof MockOptions;
    const model = models[_modelKey];

    // @ts-ignore
    if (model.id.includes("not")) {
      mockOptions[_modelKey] = false;
    } else {
      mockOptions[_modelKey] = true;
    }
  });

  emit("proceed", mockOptions);
}

这是我的接口:

export interface MockOptions {
  hasHotelComment: boolean;
  isInStornofrist: boolean;
  withDifferentBillingAddress: boolean;
  paymentOption: string;
}

我想要实现什么?
我从我的模拟数据中接收到RadioButton,以更改用于展示的数据属性。通常它们是布尔值,现在我想添加字符串,这样我就可以从所选的单选按钮设置值。然而,由于添加了'paymentOption: string',我收到了这个错误,当我切换到'boolean'时,这个错误就消失了:

TS2322: 类型'boolean'不能赋值给类型'never'。<br>const
_modelKey: keyof MockOptions

英文:

Wassup guys, can someone help me with an typing error regarding interfaces? This issue drives me crazy, I am not sure how to avoid this error without using @ts-ignore.

This is my function:

function proceed() {
  // @ts-ignore
  let mockOptions: MockOptions = {};
  Object.keys(models).forEach((modelKey) =&gt; {
    const _modelKey = modelKey as keyof MockOptions;
    const model = models[_modelKey];

    // @ts-ignore
    if (model.id.includes(&quot;not&quot;)) {
      mockOptions[_modelKey] = false;
    } else {
      mockOptions[_modelKey] = true;
    }
  });

  emit(&quot;proceed&quot;, mockOptions);
}

This is my interface:

export interface MockOptions {
  hasHotelComment: boolean;
  isInStornofrist: boolean;
  withDifferentBillingAddress: boolean;
  paymentOption: string;
}

What do I want to achieve?
I do render RadioButtons that I receive from my Mock, to change data properties for show cases. Normally they are booleans, now I want to add string so I can set values from the selected Radio. However, I receive this error, because of the added 'paymentOption: string', when I switch to 'boolean', this error disappears:

> TS2322: Type 'boolean' is not assignable to type 'never'. <br>const
> _modelKey: keyof MockOptions

答案1

得分: 1

你可以使用映射类型定义一种新类型,该类型包含所有具有布尔值的对象键:

type BooleanKeys<T> = keyof {[K in keyof T as T[K] extends boolean ? K : never]: any}

const _modelKey = modelKey as BooleanKeys<MockOptions>; // "hasHotelComment" | "isInStornofrist" | "withDifferentBillingAddress"

既然你在问,让我们逐部分解释:

type BooleanKeys<T> = keyof         // 仅获取键
 {[                                 // 来自映射类型
   K in keyof T                     // 其中键是T的键
   as                               // 但将它们强制转换为
   T[K] extends boolean ? K : never // 如果它们的值是布尔值,否则什么也不做(移除它们)
  ]: any                            // 我们丢弃值,所以任何值都可以
 }

重要的工作由as关键字完成,文档中有更多信息

英文:

You can define a new type of all object keys that hold boolean values using a mapped type:

type BooleanKeys&lt;T&gt; = keyof {[K in keyof T as T[K] extends boolean ? K : never]: any}

const _modelKey = modelKey as BooleanKeys&lt;MockOptions&gt;; // &quot;hasHotelComment&quot; | &quot;isInStornofrist&quot; | &quot;withDifferentBillingAddress&quot;

Since you were asking, let's break it down by parts:

type BooleanKeys&lt;T&gt; = keyof         // take only the keys
 {[                                 // from a mapped type
   K in keyof T                     // where keys are those of T 
   as                               // but cast them to
   T[K] extends boolean ? K : never // themself if their value is boolean, otherwise nothing (remove them)
  ]: any                            // we throw away the values, so anything is fine
 }

The heavy lifting is done by the as, the documentation has more on that.

huangapple
  • 本文由 发表于 2023年3月10日 01:35:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75688161.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定