gpt4 book ai didi

typescript - "Types of property ' X ' are incompatible"但它不是

转载 作者:搜寻专家 更新时间:2023-10-30 21:00:12 25 4
gpt4 key购买 nike

我试图创建一个接口(interface)对象,其属性从另一个对象初始化:

id: data.reference.id

属性是兼容的,但是 typescript 编译器会抛出错误。我不明白为什么以及如何避免此错误。

(后面可以找到测试代码的链接)

// INTERFACES AND TYPES
type CategoryOne = 1
type CategoryTwo = 2
type Category = CategoryOne | CategoryTwo

interface ReferenceOne {
id: string,
type: CategoryOne
}

interface ReferenceTwo {
id: string,
type: CategoryTwo
}

type Reference = ReferenceOne |  ReferenceTwo

// DIRECT INIT
let reference_OK: Reference = { // works here
id: '1',
type: 1
}

// INIT FROM DATA
interface Data {
reference: {
id: string,
type: Category
}
}

let data: Data = {
reference: {
id: '1',
type: 1
}
}

let reference_KO: Reference = { // <--- error here
id: data.reference.id, // but compatible property
type: data.reference.type // but compatible property
}

let param: Category = data.reference.type // == 1

let reference_KO2: Reference = { // <--- error here
id: data.reference.id, // but compatible property
type: param // but compatible property
}

param = 1 // == data.reference.type, same variable

let reference_OK2: Reference = { // <--- no error here
id: data.reference.id,
type: param
}

this code in Typescript playground

[更新] 我添加了从变量创建新引用的情况(reference_KO2 - 从数据属性初始化的变量 - 和 reference_OK2 - 用常量初始化的相同变量)

two behaviors with the same variable of a compatible type !

最佳答案

虽然代码在语义上看起来是正确的,但编译器会不同意,因为 Data 不保留有关类别的附加信息:它只知道字段 type 是一个类别

因此,我们知道可以为 reference_ok 分配 ReferenceOneReferenceTwoReferenceOne 要求 type 是一个 CategoryOne,而 ReferenceTwo 要求 type 是一个类别二。这些都不起作用,因为 data.reference.type 是一个通用的 Category。我们可以用更少的代码重现相同的效果,通过有目的地“向上转换”值:

let r: Reference = {
id: '1',
type: 1 as Category,
}

至少有两种方法可以避免这种情况。其中之一是将 Reference 重新定义为接口(interface),这基本上告诉编译器此时我们不需要在编译时知道类别。

interface Reference {
id: string,
type: Category,
}

然而,最吸引人的解决方案是使用泛型。我们可以扩充 Data 以包含类别的类型:

interface Data<C extends Category> {
reference: {
id: string,
type: C
}
}

此时,这段代码起作用了:

let data: Data<CategoryOne> = {
reference: {
id: '1',
type: 1
}
}

let reference_KO: Reference = {
id: data.reference.id,
type: data.reference.type
}

如果您愿意,可以将相同的处理应用于Reference

关于typescript - "Types of property ' X ' are incompatible"但它不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44931175/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com