diff --git a/src/utils/__tests__/getTSType-test.js b/src/utils/__tests__/getTSType-test.js index e636a7d4ffe..2960b2bbb36 100644 --- a/src/utils/__tests__/getTSType-test.js +++ b/src/utils/__tests__/getTSType-test.js @@ -429,6 +429,46 @@ describe('getTSType', () => { }); }); + it('handles mapped types', () => { + const typePath = statement(` + var x: { [key in 'x' | 'y']: boolean}; + `) + .get('declarations', 0) + .get('id') + .get('typeAnnotation') + .get('typeAnnotation'); + + expect(getTSType(typePath)).toEqual({ + name: 'signature', + type: 'object', + raw: "{ [key in 'x' | 'y']: boolean}", + signature: { + properties: [ + { + key: { + elements: [ + { + name: 'literal', + value: "'x'", + }, + { + name: 'literal', + value: "'y'", + }, + ], + name: 'union', + raw: "'x' | 'y'", + required: true, + }, + value: { + name: 'boolean', + }, + }, + ], + }, + }); + }); + describe('React types', () => { function test(type, expected) { const typePath = statement(` diff --git a/src/utils/getTSType.js b/src/utils/getTSType.js index 5c3f95bb652..9671c3e1e36 100644 --- a/src/utils/getTSType.js +++ b/src/utils/getTSType.js @@ -50,6 +50,7 @@ const namedTypes = { TSUnionType: handleTSUnionType, TSFunctionType: handleTSFunctionType, TSIntersectionType: handleTSIntersectionType, + TSMappedType: handleTSMappedType, TSTupleType: handleTSTupleType, TSTypeQuery: handleTSTypeQuery, TSTypeOperator: handleTSTypeOperator, @@ -214,6 +215,34 @@ function handleTSIntersectionType( }; } +function handleTSMappedType( + path: NodePath, + typeParams: ?TypeParameters, +): FlowObjectSignatureType { + const key = getTSTypeWithResolvedTypes( + path.get('typeParameter').get('constraint'), + typeParams, + ); + key.required = !path.node.optional; + + return { + name: 'signature', + type: 'object', + raw: printValue(path), + signature: { + properties: [ + { + key, + value: getTSTypeWithResolvedTypes( + path.get('typeAnnotation'), + typeParams, + ), + }, + ], + }, + }; +} + function handleTSFunctionType( path: NodePath, typeParams: ?TypeParameters,