Fix substitution types of indexed access types of substitution types (#47791)

* Fix substitution types of indexed access types of substitution types

* Add tests

* Fix accidental unindentation
This commit is contained in:
Andrew Branch 2022-02-07 15:53:13 -08:00 committed by GitHub
parent 867470ca26
commit d8ac54bfb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 126 additions and 1 deletions

View File

@ -13506,7 +13506,7 @@ namespace ts {
function getImpliedConstraint(type: Type, checkNode: TypeNode, extendsNode: TypeNode): Type | undefined {
return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(type, (checkNode as TupleTypeNode).elements[0], (extendsNode as TupleTypeNode).elements[0]) :
getActualTypeVariable(getTypeFromTypeNode(checkNode)) === type ? getTypeFromTypeNode(extendsNode) :
getActualTypeVariable(getTypeFromTypeNode(checkNode)) === getActualTypeVariable(type) ? getTypeFromTypeNode(extendsNode) :
undefined;
}

View File

@ -0,0 +1,8 @@
//// [substitutionTypeForIndexedAccessType1.ts]
type AddPropToObject<Obj extends object, Prop extends string> = Prop extends keyof Obj
? Obj[Prop] extends unknown[]
? [...Obj[Prop]]
: never
: never
//// [substitutionTypeForIndexedAccessType1.js]

View File

@ -0,0 +1,18 @@
=== tests/cases/compiler/substitutionTypeForIndexedAccessType1.ts ===
type AddPropToObject<Obj extends object, Prop extends string> = Prop extends keyof Obj
>AddPropToObject : Symbol(AddPropToObject, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 0))
>Obj : Symbol(Obj, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 21))
>Prop : Symbol(Prop, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 40))
>Prop : Symbol(Prop, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 40))
>Obj : Symbol(Obj, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 21))
? Obj[Prop] extends unknown[]
>Obj : Symbol(Obj, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 21))
>Prop : Symbol(Prop, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 40))
? [...Obj[Prop]]
>Obj : Symbol(Obj, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 21))
>Prop : Symbol(Prop, Decl(substitutionTypeForIndexedAccessType1.ts, 0, 40))
: never
: never

View File

@ -0,0 +1,8 @@
=== tests/cases/compiler/substitutionTypeForIndexedAccessType1.ts ===
type AddPropToObject<Obj extends object, Prop extends string> = Prop extends keyof Obj
>AddPropToObject : AddPropToObject<Obj, Prop>
? Obj[Prop] extends unknown[]
? [...Obj[Prop]]
: never
: never

View File

@ -0,0 +1,18 @@
//// [substitutionTypeForIndexedAccessType2.ts]
interface Foo {
foo: string|undefined
}
type Str<T extends string> = T
type Bar<T> =
T extends Foo
? T['foo'] extends string
// Type 'T["foo"]' does not satisfy the constraint 'string'.
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.(2344)
? Str<T['foo']>
: never
: never
//// [substitutionTypeForIndexedAccessType2.js]

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/substitutionTypeForIndexedAccessType2.ts ===
interface Foo {
>Foo : Symbol(Foo, Decl(substitutionTypeForIndexedAccessType2.ts, 0, 0))
foo: string|undefined
>foo : Symbol(Foo.foo, Decl(substitutionTypeForIndexedAccessType2.ts, 0, 15))
}
type Str<T extends string> = T
>Str : Symbol(Str, Decl(substitutionTypeForIndexedAccessType2.ts, 2, 1))
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 4, 9))
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 4, 9))
type Bar<T> =
>Bar : Symbol(Bar, Decl(substitutionTypeForIndexedAccessType2.ts, 4, 30))
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 6, 9))
T extends Foo
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 6, 9))
>Foo : Symbol(Foo, Decl(substitutionTypeForIndexedAccessType2.ts, 0, 0))
? T['foo'] extends string
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 6, 9))
// Type 'T["foo"]' does not satisfy the constraint 'string'.
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.(2344)
? Str<T['foo']>
>Str : Symbol(Str, Decl(substitutionTypeForIndexedAccessType2.ts, 2, 1))
>T : Symbol(T, Decl(substitutionTypeForIndexedAccessType2.ts, 6, 9))
: never
: never

View File

@ -0,0 +1,20 @@
=== tests/cases/compiler/substitutionTypeForIndexedAccessType2.ts ===
interface Foo {
foo: string|undefined
>foo : string
}
type Str<T extends string> = T
>Str : T
type Bar<T> =
>Bar : Bar<T>
T extends Foo
? T['foo'] extends string
// Type 'T["foo"]' does not satisfy the constraint 'string'.
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.(2344)
? Str<T['foo']>
: never
: never

View File

@ -0,0 +1,5 @@
type AddPropToObject<Obj extends object, Prop extends string> = Prop extends keyof Obj
? Obj[Prop] extends unknown[]
? [...Obj[Prop]]
: never
: never

View File

@ -0,0 +1,15 @@
interface Foo {
foo: string|undefined
}
type Str<T extends string> = T
type Bar<T> =
T extends Foo
? T['foo'] extends string
// Type 'T["foo"]' does not satisfy the constraint 'string'.
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.(2344)
? Str<T['foo']>
: never
: never