TypeScript 具有可选属性的类型会获得隐式的索引签名,无法显式声明,

uajslkp6  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(49)

🔎 搜索词

隐式索引签名,显式索引签名,可选部分未定义

🕗 版本与回归信息

  • 这是我尝试的每个版本的行为,我查阅了关于索引签名和未定义的常见问题解答条目

⏯ Playground链接

Playground链接

💻 代码

// @strict: true
// @exactOptionalPropertyTypes: false
// @noUncheckedIndexedAccess: false

type ObjImplicit = {
    a?: string | undefined,
    b: string
};
type Idx = { [k: string]: string }
declare const o: ObjImplicit;
const i: Idx = o; // allowed because A has implicit index signature

type ObjExplicit = {
    a?: string | undefined, // error! not allowed
    //~ <-- Property 'a' of type 'string | undefined' is not assignable to 'string' index type 'string'.
    b: string,
    [k: string]: string
}

🙁 实际行为

{ a?: string | undefined } 可以隐式具有索引签名 {[k: string]: string},但不能显式具有这样的索引签名

🙂 预期行为

我认为我期望隐式索引签名会失败?

关于此问题的其他信息

没有 --exactOptionalPropertyTypes,{a?: string}{a?: string | undefined} 是相同的类型。我以为这意味着无论是隐式还是显式地添加索引签名,都需要或不需要 undefined
我们还有 Partial<{[k: string]: string}> 变成 {[k: string]: string | undefined} 而不是 {[k: string]: string} 的情况,这使我倾向于 "需要 undefined ",以保持一致性。目前这种差异导致了诸如 this one 的问题。
无论如何,我不认为这是一个错误,而是有意为之的行为,它悄悄地出现在我的视线之外,而且我在任何地方都无法明确看到它的文档。大部分情况下,我只是想理解这种行为,这样当我遇到像上面链接的问题时,我就可以解释它了。

svujldwt

svujldwt1#

可推断的索引签名是由以下检查驱动的:

membersRelatedToIndexInfo(source2, targetInfo, reportErrors2, intersectionState)

在这里,成员与此索引签名的关系并不完全相关,因为它不包括 undefined 。TS实现了许多让步,所以这可能是有意为之的设计,但根据行为和如何命名这个函数,我认为这可能是一个bug。
编辑://嗯,我们可以在那个函数中找到这个,所以我猜它是有意为之的设计:

const type = exactOptionalPropertyTypes || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional)
    ? propType
    : getTypeWithFacts(propType, TypeFacts.NEUndefined);
enxuqcxy

enxuqcxy2#

Seems weird, especially with the existence of EOPT

相关问题