mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Merge pull request #13658 from Microsoft/findallrefs_mappedtypes
Support find-all-references on mapped types.
This commit is contained in:
@@ -4618,12 +4618,14 @@ namespace ts {
|
||||
const typeParameter = getTypeParameterFromMappedType(type);
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const templateType = getTemplateTypeFromMappedType(type);
|
||||
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type));
|
||||
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
|
||||
const templateReadonly = !!type.declaration.readonlyToken;
|
||||
const templateOptional = !!type.declaration.questionToken;
|
||||
if (type.declaration.typeParameter.constraint.kind === SyntaxKind.TypeOperator) {
|
||||
// We have a { [P in keyof T]: X }
|
||||
forEachType(getLiteralTypeFromPropertyNames(modifiersType), addMemberForKeyType);
|
||||
for (const propertySymbol of getPropertiesOfType(modifiersType)) {
|
||||
addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol);
|
||||
}
|
||||
if (getIndexInfoOfType(modifiersType, IndexKind.String)) {
|
||||
addMemberForKeyType(stringType);
|
||||
}
|
||||
@@ -4638,7 +4640,7 @@ namespace ts {
|
||||
}
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
|
||||
|
||||
function addMemberForKeyType(t: Type) {
|
||||
function addMemberForKeyType(t: Type, propertySymbol?: Symbol) {
|
||||
// Create a mapper from T to the current iteration type constituent. Then, if the
|
||||
// mapped type is itself an instantiated type, combine the iteration mapper with the
|
||||
// instantiation mapper.
|
||||
@@ -4654,6 +4656,9 @@ namespace ts {
|
||||
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
|
||||
prop.type = propType;
|
||||
prop.isReadonly = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp);
|
||||
if (propertySymbol) {
|
||||
prop.mappedTypeOrigin = propertySymbol;
|
||||
}
|
||||
members.set(propName, prop);
|
||||
}
|
||||
else if (t.flags & TypeFlags.String) {
|
||||
@@ -20233,6 +20238,10 @@ namespace ts {
|
||||
const links = symbol as SymbolLinks;
|
||||
return [links.leftSpread, links.rightSpread];
|
||||
}
|
||||
if ((symbol as SymbolLinks).mappedTypeOrigin) {
|
||||
return getRootSymbols((symbol as SymbolLinks).mappedTypeOrigin);
|
||||
}
|
||||
|
||||
let target: Symbol;
|
||||
let next = symbol;
|
||||
while (next = getSymbolLinks(next).target) {
|
||||
|
||||
@@ -2712,6 +2712,7 @@
|
||||
containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property
|
||||
leftSpread?: Symbol; // Left source for synthetic spread property
|
||||
rightSpread?: Symbol; // Right source for synthetic spread property
|
||||
mappedTypeOrigin?: Symbol; // For a property on a mapped type, points back to the orignal 'T' from 'keyof T'.
|
||||
hasNonUniformType?: boolean; // True if constituents have non-uniform types
|
||||
isPartial?: boolean; // True if syntheric property of union type occurs in some but not all constituents
|
||||
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
|
||||
|
||||
@@ -139,9 +139,9 @@ declare let x2: string;
|
||||
declare let x3: number;
|
||||
declare let x4: {
|
||||
toString: void;
|
||||
valueOf: void;
|
||||
toFixed: void;
|
||||
toExponential: void;
|
||||
toPrecision: void;
|
||||
valueOf: void;
|
||||
toLocaleString: void;
|
||||
};
|
||||
|
||||
@@ -165,7 +165,7 @@ let x3 = f3();
|
||||
>f3 : <T1 extends number>() => { [P in keyof T1]: void; }
|
||||
|
||||
let x4 = f4();
|
||||
>x4 : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; }
|
||||
>f4() : { toString: void; valueOf: void; toFixed: void; toExponential: void; toPrecision: void; toLocaleString: void; }
|
||||
>x4 : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; }
|
||||
>f4() : { toString: void; toFixed: void; toExponential: void; toPrecision: void; valueOf: void; toLocaleString: void; }
|
||||
>f4 : <T1 extends Number>() => { [P in keyof T1]: void; }
|
||||
|
||||
|
||||
9
tests/cases/fourslash/findAllRefsForMappedType.ts
Normal file
9
tests/cases/fourslash/findAllRefsForMappedType.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////interface T { [|a|]: number };
|
||||
////type U { [K in keyof T]: string };
|
||||
////type V = { [K in keyof U]: boolean };
|
||||
////const u: U = { [|a|]: "" }
|
||||
////const v: V = { [|a|]: true }
|
||||
|
||||
verify.rangesReferenceEachOther();
|
||||
Reference in New Issue
Block a user