在打字稿中,类型“x”不可分配给类型“never”

问题描述 投票:0回答:2

考虑这个类:

export const CreditRiskRatingKeys: (keyof CreditRiskRating)[] = 
[
   'applicant_id',
   'is_dirty'
];

const dict = {
  applicant_id: 'test_id',
  is_dirty: true,
}    

export class CreditRiskRating {
  applicant_id: string = '';
  is_dirty: boolean = false;

  fillQuestionDictionaryToModel() {
    for (const key of CreditRiskRatingKeys) {
      this[key] = dict[key]; // Type 'string | boolean' is not assignable to type 'never'
    }
  }
}

Key
已经是
keyof CreditRiskRating
this
指的是同一个类。那为什么
this[key] = dict[key];
要抱怨呢?我在这里缺少什么?

游乐场

typescript types casting
2个回答
1
投票

TypeScript 不会分析

CreditRiskRatingKeys
中定义的属性的值类型来尝试确定您是否为给定属性分配了正确的值类型。

一种解决方案是引入一种

Property
类型来限制列出的属性的值类型:

export type Property<T, U> = {
  [K in keyof T]: T[K] extends U ? K : never
}[keyof T];

export const CreditRiskRatingKeys: Property<CreditRiskRating, string>[] = [
   'applicant_id'
] as const;

export class CreditRiskRating {
  applicant_id: string = '';

  fillQuestionDictionaryToModel() {
    let f = this[CreditRiskRatingKeys[0]];

    for (const key of CreditRiskRatingKeys) {
      this[key] = 'test';
    }
  }
}

游乐场链接


1
投票

类型

keyof CreditRiskRating
不仅是
applicant_id
,而且还是
fillQuestionDictionaryToModel
。 JS 中的方法和属性之间没有真正的区别。

因此,尽管

CreditRiskRatingKeys
是一个只有值
applicant_id
的数组,但根据类型,它可以是具有
'applicant_id'
和/或
'fillQuestionDictionaryToModel'
的数组。因此
typeof this[key]
可以是字符串或函数
() => void

要解决此问题,您可以创建一个新的实用程序类型

PropertyOf
排除方法:

type PropertyOf<T> = {
  [K in keyof T]: T[K] extends Function ? never : K
}[keyof T];

并将其用作

export const CreditRiskRatingKeys: PropertyOf<CreditRiskRating>[] = [
   'applicant_id'
];

export class CreditRiskRating {
  applicant_id: string = '';


  fillQuestionDictionaryToModel() {
    for (const key of CreditRiskRatingKeys) {
      this[key] = 'test';
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.