Exclude mapped types with optionality modifiers and 'as' clauses from constraint logic (#48273)

* Exclude mapped types with optionality modifiers and 'as' clauses

* Add regression tests
This commit is contained in:
Anders Hejlsberg 2022-03-15 17:37:46 -07:00 committed by GitHub
parent 111ca92646
commit 8e5a84a696
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 213 additions and 3 deletions

View File

@ -12219,9 +12219,10 @@ namespace ts {
}
function isMappedTypeGenericIndexedAccess(type: Type) {
return type.flags & TypeFlags.IndexedAccess && getObjectFlags((type as IndexedAccessType).objectType) & ObjectFlags.Mapped &&
!((type as IndexedAccessType).objectType as MappedType).declaration.nameType &&
!isGenericMappedType((type as IndexedAccessType).objectType) && isGenericIndexType((type as IndexedAccessType).indexType);
let objectType;
return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped &&
!isGenericMappedType(objectType) && isGenericIndexType((type as IndexedAccessType).indexType) &&
!(objectType as MappedType).declaration.questionToken && !(objectType as MappedType).declaration.nameType);
}
/**

View File

@ -209,6 +209,31 @@ function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
}
return undefined;
}
// Repro from #48157
interface Foo {
bar?: string
}
function foo<T extends keyof Foo>(prop: T, f: Required<Foo>) {
bar(f[prop]);
}
declare function bar(t: string): void;
// Repro from #48246
declare function makeCompleteLookupMapping<T extends ReadonlyArray<any>, Attr extends keyof T[number]>(
ops: T, attr: Attr): { [Item in T[number]as Item[Attr]]: Item };
const ALL_BARS = [{ name: 'a'}, {name: 'b'}] as const;
const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
type BarLookup = typeof BAR_LOOKUP;
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
//// [correlatedUnions.js]
@ -325,6 +350,11 @@ function func(k) {
}
return undefined;
}
function foo(prop, f) {
bar(f[prop]);
}
var ALL_BARS = [{ name: 'a' }, { name: 'b' }];
var BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
//// [correlatedUnions.d.ts]
@ -451,3 +481,28 @@ interface MyObj {
}
declare const ref: MyObj;
declare function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined;
interface Foo {
bar?: string;
}
declare function foo<T extends keyof Foo>(prop: T, f: Required<Foo>): void;
declare function bar(t: string): void;
declare function makeCompleteLookupMapping<T extends ReadonlyArray<any>, Attr extends keyof T[number]>(ops: T, attr: Attr): {
[Item in T[number] as Item[Attr]]: Item;
};
declare const ALL_BARS: readonly [{
readonly name: "a";
}, {
readonly name: "b";
}];
declare const BAR_LOOKUP: {
a: {
readonly name: "a";
};
b: {
readonly name: "b";
};
};
declare type BarLookup = typeof BAR_LOOKUP;
declare type Baz = {
[K in keyof BarLookup]: BarLookup[K]['name'];
};

View File

@ -753,3 +753,74 @@ function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
>undefined : Symbol(undefined)
}
// Repro from #48157
interface Foo {
>Foo : Symbol(Foo, Decl(correlatedUnions.ts, 209, 1))
bar?: string
>bar : Symbol(Foo.bar, Decl(correlatedUnions.ts, 213, 15))
}
function foo<T extends keyof Foo>(prop: T, f: Required<Foo>) {
>foo : Symbol(foo, Decl(correlatedUnions.ts, 215, 1))
>T : Symbol(T, Decl(correlatedUnions.ts, 217, 13))
>Foo : Symbol(Foo, Decl(correlatedUnions.ts, 209, 1))
>prop : Symbol(prop, Decl(correlatedUnions.ts, 217, 34))
>T : Symbol(T, Decl(correlatedUnions.ts, 217, 13))
>f : Symbol(f, Decl(correlatedUnions.ts, 217, 42))
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
>Foo : Symbol(Foo, Decl(correlatedUnions.ts, 209, 1))
bar(f[prop]);
>bar : Symbol(bar, Decl(correlatedUnions.ts, 219, 1))
>f : Symbol(f, Decl(correlatedUnions.ts, 217, 42))
>prop : Symbol(prop, Decl(correlatedUnions.ts, 217, 34))
}
declare function bar(t: string): void;
>bar : Symbol(bar, Decl(correlatedUnions.ts, 219, 1))
>t : Symbol(t, Decl(correlatedUnions.ts, 221, 21))
// Repro from #48246
declare function makeCompleteLookupMapping<T extends ReadonlyArray<any>, Attr extends keyof T[number]>(
>makeCompleteLookupMapping : Symbol(makeCompleteLookupMapping, Decl(correlatedUnions.ts, 221, 38))
>T : Symbol(T, Decl(correlatedUnions.ts, 225, 43))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
>Attr : Symbol(Attr, Decl(correlatedUnions.ts, 225, 72))
>T : Symbol(T, Decl(correlatedUnions.ts, 225, 43))
ops: T, attr: Attr): { [Item in T[number]as Item[Attr]]: Item };
>ops : Symbol(ops, Decl(correlatedUnions.ts, 225, 103))
>T : Symbol(T, Decl(correlatedUnions.ts, 225, 43))
>attr : Symbol(attr, Decl(correlatedUnions.ts, 226, 11))
>Attr : Symbol(Attr, Decl(correlatedUnions.ts, 225, 72))
>Item : Symbol(Item, Decl(correlatedUnions.ts, 226, 28))
>T : Symbol(T, Decl(correlatedUnions.ts, 225, 43))
>Item : Symbol(Item, Decl(correlatedUnions.ts, 226, 28))
>Attr : Symbol(Attr, Decl(correlatedUnions.ts, 225, 72))
>Item : Symbol(Item, Decl(correlatedUnions.ts, 226, 28))
const ALL_BARS = [{ name: 'a'}, {name: 'b'}] as const;
>ALL_BARS : Symbol(ALL_BARS, Decl(correlatedUnions.ts, 228, 5))
>name : Symbol(name, Decl(correlatedUnions.ts, 228, 19))
>name : Symbol(name, Decl(correlatedUnions.ts, 228, 33))
>const : Symbol(const)
const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
>BAR_LOOKUP : Symbol(BAR_LOOKUP, Decl(correlatedUnions.ts, 230, 5))
>makeCompleteLookupMapping : Symbol(makeCompleteLookupMapping, Decl(correlatedUnions.ts, 221, 38))
>ALL_BARS : Symbol(ALL_BARS, Decl(correlatedUnions.ts, 228, 5))
type BarLookup = typeof BAR_LOOKUP;
>BarLookup : Symbol(BarLookup, Decl(correlatedUnions.ts, 230, 63))
>BAR_LOOKUP : Symbol(BAR_LOOKUP, Decl(correlatedUnions.ts, 230, 5))
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
>Baz : Symbol(Baz, Decl(correlatedUnions.ts, 232, 35))
>K : Symbol(K, Decl(correlatedUnions.ts, 234, 14))
>BarLookup : Symbol(BarLookup, Decl(correlatedUnions.ts, 230, 63))
>BarLookup : Symbol(BarLookup, Decl(correlatedUnions.ts, 230, 63))
>K : Symbol(K, Decl(correlatedUnions.ts, 234, 14))

View File

@ -695,3 +695,61 @@ function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
>undefined : undefined
}
// Repro from #48157
interface Foo {
bar?: string
>bar : string | undefined
}
function foo<T extends keyof Foo>(prop: T, f: Required<Foo>) {
>foo : <T extends "bar">(prop: T, f: Required<Foo>) => void
>prop : T
>f : Required<Foo>
bar(f[prop]);
>bar(f[prop]) : void
>bar : (t: string) => void
>f[prop] : Required<Foo>[T]
>f : Required<Foo>
>prop : T
}
declare function bar(t: string): void;
>bar : (t: string) => void
>t : string
// Repro from #48246
declare function makeCompleteLookupMapping<T extends ReadonlyArray<any>, Attr extends keyof T[number]>(
>makeCompleteLookupMapping : <T extends readonly any[], Attr extends keyof T[number]>(ops: T, attr: Attr) => { [Item in T[number] as Item[Attr]]: Item; }
ops: T, attr: Attr): { [Item in T[number]as Item[Attr]]: Item };
>ops : T
>attr : Attr
const ALL_BARS = [{ name: 'a'}, {name: 'b'}] as const;
>ALL_BARS : readonly [{ readonly name: "a"; }, { readonly name: "b"; }]
>[{ name: 'a'}, {name: 'b'}] as const : readonly [{ readonly name: "a"; }, { readonly name: "b"; }]
>[{ name: 'a'}, {name: 'b'}] : readonly [{ readonly name: "a"; }, { readonly name: "b"; }]
>{ name: 'a'} : { readonly name: "a"; }
>name : "a"
>'a' : "a"
>{name: 'b'} : { readonly name: "b"; }
>name : "b"
>'b' : "b"
const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
>BAR_LOOKUP : { a: { readonly name: "a"; }; b: { readonly name: "b"; }; }
>makeCompleteLookupMapping(ALL_BARS, 'name') : { a: { readonly name: "a"; }; b: { readonly name: "b"; }; }
>makeCompleteLookupMapping : <T extends readonly any[], Attr extends keyof T[number]>(ops: T, attr: Attr) => { [Item in T[number] as Item[Attr]]: Item; }
>ALL_BARS : readonly [{ readonly name: "a"; }, { readonly name: "b"; }]
>'name' : "name"
type BarLookup = typeof BAR_LOOKUP;
>BarLookup : { a: { readonly name: "a"; }; b: { readonly name: "b"; }; }
>BAR_LOOKUP : { a: { readonly name: "a"; }; b: { readonly name: "b"; }; }
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };
>Baz : Baz

View File

@ -211,3 +211,28 @@ function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
}
return undefined;
}
// Repro from #48157
interface Foo {
bar?: string
}
function foo<T extends keyof Foo>(prop: T, f: Required<Foo>) {
bar(f[prop]);
}
declare function bar(t: string): void;
// Repro from #48246
declare function makeCompleteLookupMapping<T extends ReadonlyArray<any>, Attr extends keyof T[number]>(
ops: T, attr: Attr): { [Item in T[number]as Item[Attr]]: Item };
const ALL_BARS = [{ name: 'a'}, {name: 'b'}] as const;
const BAR_LOOKUP = makeCompleteLookupMapping(ALL_BARS, 'name');
type BarLookup = typeof BAR_LOOKUP;
type Baz = { [K in keyof BarLookup]: BarLookup[K]['name'] };