Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10458,7 +10458,7 @@ namespace ts {
existingProp.keyType = getUnionType([existingProp.keyType, keyType]);
}
else {
const modifiersProp = getPropertyOfType(modifiersType, propName);
const modifiersProp = isTypeUsableAsPropertyName(keyType) ? getPropertyOfType(modifiersType, getPropertyNameFromType(keyType)) : undefined;
const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional ||
!(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly ||
Expand Down
23 changes: 23 additions & 0 deletions tests/baselines/reference/mappedTypeAsClauses.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`

// Repro from #40619

type Lazyify<T> = {
[K in keyof T as `get${capitalize string & K}`]: () => T[K]
};

interface Person {
readonly name: string;
age: number;
location?: string;
}

type LazyPerson = Lazyify<Person>;


//// [mappedTypeAsClauses.js]
Expand Down Expand Up @@ -82,3 +96,12 @@ declare type TD1 = DoubleProp<{
}>;
declare type TD2 = keyof TD1;
declare type TD3<U> = keyof DoubleProp<U>;
declare type Lazyify<T> = {
[K in keyof T as `get${capitalize string & K}`]: () => T[K];
};
interface Person {
readonly name: string;
age: number;
location?: string;
}
declare type LazyPerson = Lazyify<Person>;
33 changes: 33 additions & 0 deletions tests/baselines/reference/mappedTypeAsClauses.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,36 @@ type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & str
>DoubleProp : Symbol(DoubleProp, Decl(mappedTypeAsClauses.ts, 21, 85))
>U : Symbol(U, Decl(mappedTypeAsClauses.ts, 28, 9))

// Repro from #40619

type Lazyify<T> = {
>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))

[K in keyof T as `get${capitalize string & K}`]: () => T[K]
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))
>T : Symbol(T, Decl(mappedTypeAsClauses.ts, 32, 13))
>K : Symbol(K, Decl(mappedTypeAsClauses.ts, 33, 5))

};

interface Person {
>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2))

readonly name: string;
>name : Symbol(Person.name, Decl(mappedTypeAsClauses.ts, 36, 18))

age: number;
>age : Symbol(Person.age, Decl(mappedTypeAsClauses.ts, 37, 26))

location?: string;
>location : Symbol(Person.location, Decl(mappedTypeAsClauses.ts, 38, 16))
}

type LazyPerson = Lazyify<Person>;
>LazyPerson : Symbol(LazyPerson, Decl(mappedTypeAsClauses.ts, 40, 1))
>Lazyify : Symbol(Lazyify, Decl(mappedTypeAsClauses.ts, 28, 34))
>Person : Symbol(Person, Decl(mappedTypeAsClauses.ts, 34, 2))

22 changes: 22 additions & 0 deletions tests/baselines/reference/mappedTypeAsClauses.types
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,25 @@ type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`
>TD3 : `${keyof U & string}1` | `${keyof U & string}2`

// Repro from #40619

type Lazyify<T> = {
>Lazyify : Lazyify<T>

[K in keyof T as `get${capitalize string & K}`]: () => T[K]
};

interface Person {
readonly name: string;
>name : string

age: number;
>age : number

location?: string;
>location : string | undefined
}

type LazyPerson = Lazyify<Person>;
>LazyPerson : Lazyify<Person>

14 changes: 14 additions & 0 deletions tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,17 @@ type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2'
type TD3<U> = keyof DoubleProp<U>; // `${keyof U & string}1` | `${keyof U & string}2`

// Repro from #40619

type Lazyify<T> = {
[K in keyof T as `get${capitalize string & K}`]: () => T[K]
};

interface Person {
readonly name: string;
age: number;
location?: string;
}

type LazyPerson = Lazyify<Person>;