Skip to content

Commit

Permalink
🤖 Pick PR #53207 (Fixed symbol declarations for gener...) into releas…
Browse files Browse the repository at this point in the history
…e-5.0 (#53271)

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
  • Loading branch information
TypeScript Bot and Andarist authored Mar 28, 2023
1 parent 1e70bb8 commit 111df34
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
17 changes: 11 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13179,9 +13179,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// and T as the template type.
const typeParameter = getTypeParameterFromMappedType(type);
const constraintType = getConstraintTypeFromMappedType(type);
const nameType = getNameTypeFromMappedType(type.target as MappedType || type);
const isFilteringMappedType = nameType && isTypeAssignableTo(nameType, typeParameter);
const templateType = getTemplateTypeFromMappedType(type.target as MappedType || type);
const mappedType = (type.target as MappedType) || type;
const nameType = getNameTypeFromMappedType(mappedType);
const shouldLinkPropDeclarations = !nameType || isFilteringMappedType(mappedType);
const templateType = getTemplateTypeFromMappedType(mappedType);
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
const templateModifiers = getMappedTypeModifiers(type);
const include = keyofStringsOnly ? TypeFlags.StringLiteral : TypeFlags.StringOrNumberLiteralOrUnique;
Expand Down Expand Up @@ -13227,7 +13228,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
prop.links.keyType = keyType;
if (modifiersProp) {
prop.links.syntheticOrigin = modifiersProp;
prop.declarations = !nameType || isFilteringMappedType ? modifiersProp.declarations : undefined;
prop.declarations = shouldLinkPropDeclarations ? modifiersProp.declarations : undefined;
}
members.set(propName, prop);
}
Expand Down Expand Up @@ -13360,6 +13361,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return false;
}

function isFilteringMappedType(type: MappedType): boolean {
const nameType = getNameTypeFromMappedType(type);
return !!nameType && isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type));
}

function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
if (!(type as ResolvedType).members) {
if (type.flags & TypeFlags.Object) {
Expand Down Expand Up @@ -17488,8 +17494,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// K is generic and N is assignable to P, instantiate E using a mapper that substitutes the index type for P.
// For example, for an index access { [P in K]: Box<T[P]> }[X], we construct the type Box<T[X]>.
if (isGenericMappedType(objectType)) {
const nameType = getNameTypeFromMappedType(objectType);
if (!nameType || isTypeAssignableTo(nameType, getTypeParameterFromMappedType(objectType))) {
if (!getNameTypeFromMappedType(objectType) || isFilteringMappedType(objectType)) {
return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing));
}
}
Expand Down
25 changes: 25 additions & 0 deletions tests/cases/fourslash/goToDefinition_filteringGenericMappedType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
///<reference path="fourslash.ts"/>

//// const obj = {
//// get /*def*/id() {
//// return 1;
//// },
//// name: "test",
//// };
////
//// type Omit2<T, DroppedKeys extends PropertyKey> = {
//// [K in keyof T as Exclude<K, DroppedKeys>]: T[K];
//// };
////
//// declare function omit2<O, Mask extends { [K in keyof O]?: true }>(
//// obj: O,
//// mask: Mask
//// ): Omit2<O, keyof Mask>;
////
//// const obj2 = omit2(obj, {
//// name: true,
//// });
////
//// obj2.[|/*ref*/id|];

verify.goToDefinition("ref", "def");

0 comments on commit 111df34

Please sign in to comment.