Skip to content

Commit 2976b6b

Browse files
authored
Filtering mapped types declarations (#51650)
1 parent 55eff14 commit 2976b6b

7 files changed

+451
-16
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13064,6 +13064,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1306413064
const typeParameter = getTypeParameterFromMappedType(type);
1306513065
const constraintType = getConstraintTypeFromMappedType(type);
1306613066
const nameType = getNameTypeFromMappedType(type.target as MappedType || type);
13067+
const isFilteringMappedType = nameType && isTypeAssignableTo(nameType, typeParameter);
1306713068
const templateType = getTemplateTypeFromMappedType(type.target as MappedType || type);
1306813069
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
1306913070
const templateModifiers = getMappedTypeModifiers(type);
@@ -13110,9 +13111,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1311013111
prop.links.keyType = keyType;
1311113112
if (modifiersProp) {
1311213113
prop.links.syntheticOrigin = modifiersProp;
13113-
// If the mapped type has an `as XXX` clause, the property name likely won't match the declaration name and
13114-
// multiple properties may map to the same name. Thus, we attach no declarations to the symbol.
13115-
prop.declarations = nameType ? undefined : modifiersProp.declarations;
13114+
prop.declarations = !nameType || isFilteringMappedType ? modifiersProp.declarations : undefined;
1311613115
}
1311713116
members.set(propName, prop);
1311813117
}
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
// === /tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts ===
2+
// const obj = { /*FIND ALL REFS*/[|a|]: 1, b: 2 };
3+
// const filtered: { [P in keyof typeof obj as P extends 'b' ? never : P]: 0; } = { [|a|]: 0 };
4+
// filtered.[|a|];
5+
6+
[
7+
{
8+
"definition": {
9+
"containerKind": "",
10+
"containerName": "",
11+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
12+
"kind": "property",
13+
"name": "(property) a: number",
14+
"textSpan": {
15+
"start": 14,
16+
"length": 1
17+
},
18+
"displayParts": [
19+
{
20+
"text": "(",
21+
"kind": "punctuation"
22+
},
23+
{
24+
"text": "property",
25+
"kind": "text"
26+
},
27+
{
28+
"text": ")",
29+
"kind": "punctuation"
30+
},
31+
{
32+
"text": " ",
33+
"kind": "space"
34+
},
35+
{
36+
"text": "a",
37+
"kind": "propertyName"
38+
},
39+
{
40+
"text": ":",
41+
"kind": "punctuation"
42+
},
43+
{
44+
"text": " ",
45+
"kind": "space"
46+
},
47+
{
48+
"text": "number",
49+
"kind": "keyword"
50+
}
51+
],
52+
"contextSpan": {
53+
"start": 14,
54+
"length": 4
55+
}
56+
},
57+
"references": [
58+
{
59+
"textSpan": {
60+
"start": 14,
61+
"length": 1
62+
},
63+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
64+
"contextSpan": {
65+
"start": 14,
66+
"length": 4
67+
},
68+
"isWriteAccess": true,
69+
"isDefinition": true
70+
},
71+
{
72+
"textSpan": {
73+
"start": 109,
74+
"length": 1
75+
},
76+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
77+
"contextSpan": {
78+
"start": 109,
79+
"length": 4
80+
},
81+
"isWriteAccess": true,
82+
"isDefinition": false
83+
},
84+
{
85+
"textSpan": {
86+
"start": 126,
87+
"length": 1
88+
},
89+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
90+
"isWriteAccess": false,
91+
"isDefinition": false
92+
}
93+
]
94+
}
95+
]
96+
97+
// === /tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts ===
98+
// const obj = { [|a|]: 1, b: 2 };
99+
// const filtered: { [P in keyof typeof obj as P extends 'b' ? never : P]: 0; } = { /*FIND ALL REFS*/[|a|]: 0 };
100+
// filtered.[|a|];
101+
102+
[
103+
{
104+
"definition": {
105+
"containerKind": "",
106+
"containerName": "",
107+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
108+
"kind": "property",
109+
"name": "(property) a: number",
110+
"textSpan": {
111+
"start": 14,
112+
"length": 1
113+
},
114+
"displayParts": [
115+
{
116+
"text": "(",
117+
"kind": "punctuation"
118+
},
119+
{
120+
"text": "property",
121+
"kind": "text"
122+
},
123+
{
124+
"text": ")",
125+
"kind": "punctuation"
126+
},
127+
{
128+
"text": " ",
129+
"kind": "space"
130+
},
131+
{
132+
"text": "a",
133+
"kind": "propertyName"
134+
},
135+
{
136+
"text": ":",
137+
"kind": "punctuation"
138+
},
139+
{
140+
"text": " ",
141+
"kind": "space"
142+
},
143+
{
144+
"text": "number",
145+
"kind": "keyword"
146+
}
147+
],
148+
"contextSpan": {
149+
"start": 14,
150+
"length": 4
151+
}
152+
},
153+
"references": [
154+
{
155+
"textSpan": {
156+
"start": 14,
157+
"length": 1
158+
},
159+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
160+
"contextSpan": {
161+
"start": 14,
162+
"length": 4
163+
},
164+
"isWriteAccess": true,
165+
"isDefinition": false
166+
},
167+
{
168+
"textSpan": {
169+
"start": 109,
170+
"length": 1
171+
},
172+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
173+
"contextSpan": {
174+
"start": 109,
175+
"length": 4
176+
},
177+
"isWriteAccess": true,
178+
"isDefinition": true
179+
},
180+
{
181+
"textSpan": {
182+
"start": 126,
183+
"length": 1
184+
},
185+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
186+
"isWriteAccess": false,
187+
"isDefinition": false
188+
}
189+
]
190+
}
191+
]
192+
193+
// === /tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts ===
194+
// const obj = { [|a|]: 1, b: 2 };
195+
// const filtered: { [P in keyof typeof obj as P extends 'b' ? never : P]: 0; } = { [|a|]: 0 };
196+
// filtered./*FIND ALL REFS*/[|a|];
197+
198+
[
199+
{
200+
"definition": {
201+
"containerKind": "",
202+
"containerName": "",
203+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
204+
"kind": "property",
205+
"name": "(property) a: number",
206+
"textSpan": {
207+
"start": 14,
208+
"length": 1
209+
},
210+
"displayParts": [
211+
{
212+
"text": "(",
213+
"kind": "punctuation"
214+
},
215+
{
216+
"text": "property",
217+
"kind": "text"
218+
},
219+
{
220+
"text": ")",
221+
"kind": "punctuation"
222+
},
223+
{
224+
"text": " ",
225+
"kind": "space"
226+
},
227+
{
228+
"text": "a",
229+
"kind": "propertyName"
230+
},
231+
{
232+
"text": ":",
233+
"kind": "punctuation"
234+
},
235+
{
236+
"text": " ",
237+
"kind": "space"
238+
},
239+
{
240+
"text": "number",
241+
"kind": "keyword"
242+
}
243+
],
244+
"contextSpan": {
245+
"start": 14,
246+
"length": 4
247+
}
248+
},
249+
"references": [
250+
{
251+
"textSpan": {
252+
"start": 14,
253+
"length": 1
254+
},
255+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
256+
"contextSpan": {
257+
"start": 14,
258+
"length": 4
259+
},
260+
"isWriteAccess": true
261+
},
262+
{
263+
"textSpan": {
264+
"start": 109,
265+
"length": 1
266+
},
267+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
268+
"contextSpan": {
269+
"start": 109,
270+
"length": 4
271+
},
272+
"isWriteAccess": true
273+
},
274+
{
275+
"textSpan": {
276+
"start": 126,
277+
"length": 1
278+
},
279+
"fileName": "/tests/cases/fourslash/findAllReferencesFilteringMappedTypeProperty.ts",
280+
"isWriteAccess": false
281+
}
282+
]
283+
}
284+
]

0 commit comments

Comments
 (0)