Skip to content

Commit

Permalink
Fixed types of properties of contextual filtering mapped types (#56201)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist authored Aug 8, 2024
1 parent 9987812 commit 3cf708e
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31620,7 +31620,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
return mapType(type, t => {
if (isGenericMappedType(t) && !t.declaration.nameType) {
if (isGenericMappedType(t) && getMappedTypeNameTypeKind(t) !== MappedTypeNameTypeKind.Remapping) {
const constraint = getConstraintTypeFromMappedType(t);
const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
const propertyNameType = nameType || getStringLiteralType(unescapeLeadingUnderscores(name));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//// [tests/cases/compiler/contextualPropertyOfGenericFilteringMappedType.ts] ////

=== contextualPropertyOfGenericFilteringMappedType.ts ===
declare function f1<T extends object>(
>f1 : Symbol(f1, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 0))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 20))

data: T,
>data : Symbol(data, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 38))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 20))

handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void },
>handlers : Symbol(handlers, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 1, 10))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 15))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 20))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 15))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 36))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 20))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 15))
>prop : Symbol(prop, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 48))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 2, 15))

): void;

f1(
>f1 : Symbol(f1, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 0, 0))
{
foo: 0,
>foo : Symbol(foo, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 6, 3))

bar: "",
>bar : Symbol(bar, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 7, 11))

},
{
foo: (value, key) => {},
>foo : Symbol(foo, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 10, 3))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 11, 10))
>key : Symbol(key, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 11, 16))

bar: (value, key) => {},
>bar : Symbol(bar, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 11, 28))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 12, 10))
>key : Symbol(key, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 12, 16))

},
);

declare function f2<T extends object>(
>f2 : Symbol(f2, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 14, 2))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 20))

data: T,
>data : Symbol(data, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 38))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 20))

handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void },
>handlers : Symbol(handlers, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 17, 10))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 15))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 20))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 20))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 15))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 15))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 66))
>T : Symbol(T, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 16, 20))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 15))
>prop : Symbol(prop, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 78))
>P : Symbol(P, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 18, 15))

): void;

f2(
>f2 : Symbol(f2, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 14, 2))
{
foo: 0,
>foo : Symbol(foo, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 22, 3))

bar: "",
>bar : Symbol(bar, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 23, 11))

},
{
bar: (value, key) => {},
>bar : Symbol(bar, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 26, 3))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 27, 10))
>key : Symbol(key, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 27, 16))

},
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//// [tests/cases/compiler/contextualPropertyOfGenericFilteringMappedType.ts] ////

=== contextualPropertyOfGenericFilteringMappedType.ts ===
declare function f1<T extends object>(
>f1 : <T extends object>(data: T, handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void; }) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^

data: T,
>data : T
> : ^

handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void },
>handlers : { [P in keyof T as P]: (value: T[P], prop: P) => void; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^^^^ ^^^
>value : T[P]
> : ^^^^
>prop : P
> : ^

): void;

f1(
>f1( { foo: 0, bar: "", }, { foo: (value, key) => {}, bar: (value, key) => {}, },) : void
> : ^^^^
>f1 : <T extends object>(data: T, handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void; }) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
{
>{ foo: 0, bar: "", } : { foo: number; bar: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

foo: 0,
>foo : number
> : ^^^^^^
>0 : 0
> : ^

bar: "",
>bar : string
> : ^^^^^^
>"" : ""
> : ^^

},
{
>{ foo: (value, key) => {}, bar: (value, key) => {}, } : { foo: (value: number, key: "foo") => void; bar: (value: string, key: "bar") => void; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

foo: (value, key) => {},
>foo : (value: number, key: "foo") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>(value, key) => {} : (value: number, key: "foo") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>value : number
> : ^^^^^^
>key : "foo"
> : ^^^^^

bar: (value, key) => {},
>bar : (value: string, key: "bar") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>(value, key) => {} : (value: string, key: "bar") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>value : string
> : ^^^^^^
>key : "bar"
> : ^^^^^

},
);

declare function f2<T extends object>(
>f2 : <T extends object>(data: T, handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void; }) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^

data: T,
>data : T
> : ^

handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void },
>handlers : { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void; }
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^^^^ ^^^
>value : T[P]
> : ^^^^
>prop : P
> : ^

): void;

f2(
>f2( { foo: 0, bar: "", }, { bar: (value, key) => {}, },) : void
> : ^^^^
>f2 : <T extends object>(data: T, handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void; }) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
{
>{ foo: 0, bar: "", } : { foo: number; bar: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

foo: 0,
>foo : number
> : ^^^^^^
>0 : 0
> : ^

bar: "",
>bar : string
> : ^^^^^^
>"" : ""
> : ^^

},
{
>{ bar: (value, key) => {}, } : { bar: (value: string, key: "bar") => void; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

bar: (value, key) => {},
>bar : (value: string, key: "bar") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>(value, key) => {} : (value: string, key: "bar") => void
> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
>value : string
> : ^^^^^^
>key : "bar"
> : ^^^^^

},
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @strict: true
// @noEmit: true

declare function f1<T extends object>(
data: T,
handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void },
): void;

f1(
{
foo: 0,
bar: "",
},
{
foo: (value, key) => {},
bar: (value, key) => {},
},
);

declare function f2<T extends object>(
data: T,
handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void },
): void;

f2(
{
foo: 0,
bar: "",
},
{
bar: (value, key) => {},
},
);

0 comments on commit 3cf708e

Please sign in to comment.