Skip to content

Commit c1dce84

Browse files
thchiadanez
authored andcommitted
fix: Expand index types correctly (#369)
1 parent 53a7a55 commit c1dce84

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/utils/__tests__/getTSType-test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,38 @@ describe('getTSType', () => {
315315
});
316316
});
317317

318+
it('detects indexed access', () => {
319+
const typePath = statement(`
320+
var x: A["x"] = 2;
321+
322+
interface A { x: string };
323+
`)
324+
.get('declarations', 0)
325+
.get('id')
326+
.get('typeAnnotation')
327+
.get('typeAnnotation');
328+
expect(getTSType(typePath)).toEqual({
329+
name: 'A["x"]',
330+
raw: 'A["x"]',
331+
});
332+
});
333+
334+
it('resolves indexed access', () => {
335+
const typePath = statement(`
336+
var x: A["x"] = 2;
337+
338+
type A = { x: string };
339+
`)
340+
.get('declarations', 0)
341+
.get('id')
342+
.get('typeAnnotation')
343+
.get('typeAnnotation');
344+
expect(getTSType(typePath)).toEqual({
345+
name: 'string',
346+
raw: 'A["x"]',
347+
});
348+
});
349+
318350
it('resolves types in scope', () => {
319351
const typePath = statement(`
320352
var x: MyType = 2;

src/utils/getTSType.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import getTypeParameters, {
1919
import type {
2020
FlowElementsType,
2121
FlowFunctionArgumentType,
22+
FlowLiteralType,
2223
FlowObjectSignatureType,
2324
FlowSimpleType,
2425
FlowTypeDescriptor,
@@ -54,6 +55,7 @@ const namedTypes = {
5455
TSTupleType: handleTSTupleType,
5556
TSTypeQuery: handleTSTypeQuery,
5657
TSTypeOperator: handleTSTypeOperator,
58+
TSIndexedAccessType: handleTSIndexedAccessType,
5759
};
5860

5961
function handleTSArrayType(
@@ -347,6 +349,40 @@ function handleTSTypeOperator(path: NodePath): ?FlowTypeDescriptor {
347349
}
348350
}
349351

352+
function handleTSIndexedAccessType(
353+
path: NodePath,
354+
typeParams: ?TypeParameters,
355+
): FlowSimpleType {
356+
// eslint-disable-next-line no-undef
357+
const objectType: $Shape<FlowObjectSignatureType> = getTSTypeWithResolvedTypes(
358+
path.get('objectType'),
359+
typeParams,
360+
);
361+
// eslint-disable-next-line no-undef
362+
const indexType: $Shape<FlowLiteralType> = getTSTypeWithResolvedTypes(
363+
path.get('indexType'),
364+
typeParams,
365+
);
366+
367+
// We only get the signature if the objectType is a type (vs interface)
368+
if (!objectType.signature)
369+
return {
370+
name: `${objectType.name}[${indexType.value.toString()}]`,
371+
raw: printValue(path),
372+
};
373+
const resolvedType = objectType.signature.properties.find(p => {
374+
// indexType.value = "'foo'"
375+
return p.key === indexType.value.replace(/['"]+/g, '');
376+
});
377+
if (!resolvedType) {
378+
return { name: 'unknown' };
379+
}
380+
return {
381+
name: resolvedType.value.name,
382+
raw: printValue(path),
383+
};
384+
}
385+
350386
let visitedTypes = {};
351387

352388
function getTSTypeWithResolvedTypes(

0 commit comments

Comments
 (0)