以下代码编译:
type Ugh = {
boo: {[s: string]: Ugh },
baz: ({ [P in keyof Ugh["boo"]]: Ugh["boo"][P] extends Ugh ? Ugh["boo"][P] : string })
};
const q: Ugh = { boo: {}, baz: {}};
const v: Ugh = {boo: { why: { boo: {}, baz: {}}}, baz: { why: { boo: {}, baz: {}} }};
以下内容不
type Ugh = {
boo: {[s: string]: string | Ugh },
baz: ({ [P in keyof Ugh["boo"]]: Ugh["boo"][P] extends Ugh ? Ugh["boo"][P] : string })
};
const q: Ugh = { boo: {}, baz: {}};
const v: Ugh = {boo: { why: { boo: {}, baz: {}}}, baz: { why: { boo: {}, baz: {}} }};
唯一的区别是boo
的类型。为什么第二个不编译?
答案 0 :(得分:1)
为什么第二个不编译?
类型string | Ugh
不会扩展类型Ugh
,因此在第二个示例中,Ugh["boo"][P] extends Ugh
将始终为false
,结果是baz
始终为string
类型。
在代码注释(and in the playground)中:
type Ugh = {
// The string index type of Ugh...
boo: {
[s: string]: string
},
baz: (
{
// means that P will always be an Ugh...
// which does extend Ugh...
[P in keyof Ugh["boo"]]: Ugh["boo"][P] extends Ugh
// and so this will always resolve to an Ugh.
? Ugh["boo"][P]
: string
}
)
};
type t1 = Ugh["boo"][string] extends Ugh ? true : false; // true
type UghToo = {
// The string index type of string | UghToo...
boo: { [s: string]: string | UghToo },
baz: ({
// means that P will always be a string | UghToo...
// which does not extend UghToo...
[P in keyof UghToo["boo"]]: UghToo["boo"][P] extends UghToo
? UghToo["boo"][P]
// and so this will always resolve to a string.
: string
})
};
type t2 = UghToo["boo"][string] extends UghToo ? true : false; // false
通常,两种类型的联合(几乎没有例外)不会扩展这两种类型中的任何一种。
type t3 = Date extends Date ? true : false; // true
type t4 = string | Date extends Date ? true : false; // false
type t5 = string | Date extends string ? true : false; // false