Skip to content

Commit

Permalink
fix: Correctly handle ObjectTypeSpreadProperty in object type annotat…
Browse files Browse the repository at this point in the history
…ions (#593)

Co-authored-by: Daniel Tschinder <231804+danez@users.noreply.github.com>
  • Loading branch information
imdreamrunner and danez committed May 28, 2022
1 parent 997c7da commit 4718d8b
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/utils/__tests__/__snapshots__/getFlowType-test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getFlowType handles ObjectTypeSpreadProperty 1`] = `
Object {
"name": "signature",
"raw": "{| apple: string, banana: string, ...OtherFruits |}",
"signature": Object {
"properties": Array [
Object {
"key": "apple",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "banana",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "orange",
"value": Object {
"name": "string",
"required": true,
},
},
],
},
"type": "object",
}
`;

exports[`getFlowType handles nested ObjectTypeSpreadProperty 1`] = `
Object {
"name": "signature",
"raw": "{| apple: string, banana: string, ...BreakfastFruits |}",
"signature": Object {
"properties": Array [
Object {
"key": "apple",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "banana",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "mango",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "orange",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "lemon",
"value": Object {
"name": "string",
"required": true,
},
},
],
},
"type": "object",
}
`;

exports[`getFlowType handles unresolved ObjectTypeSpreadProperty 1`] = `
Object {
"name": "signature",
"raw": "{| apple: string, banana: string, ...MyType |}",
"signature": Object {
"properties": Array [
Object {
"key": "apple",
"value": Object {
"name": "string",
"required": true,
},
},
Object {
"key": "banana",
"value": Object {
"name": "string",
"required": true,
},
},
],
},
"type": "object",
}
`;
39 changes: 39 additions & 0 deletions src/utils/__tests__/getFlowType-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -745,4 +745,43 @@ describe('getFlowType', () => {
raw: '{ subAction: SubAction }',
});
});

it('handles ObjectTypeSpreadProperty', () => {
const typePath = statement(`
var x: {| apple: string, banana: string, ...OtherFruits |} = 2;
type OtherFruits = { orange: string }
`)
.get('declarations', 0)
.get('id')
.get('typeAnnotation')
.get('typeAnnotation');

expect(getFlowType(typePath)).toMatchSnapshot();
});

it('handles unresolved ObjectTypeSpreadProperty', () => {
const typePath = statement(`
var x: {| apple: string, banana: string, ...MyType |} = 2;
`)
.get('declarations', 0)
.get('id')
.get('typeAnnotation')
.get('typeAnnotation');

expect(getFlowType(typePath)).toMatchSnapshot();
});

it('handles nested ObjectTypeSpreadProperty', () => {
const typePath = statement(`
var x: {| apple: string, banana: string, ...BreakfastFruits |} = 2;
type BreakfastFruits = { mango: string, ...CitrusFruits };
type CitrusFruits = { orange: string, lemon: string };
`)
.get('declarations', 0)
.get('id')
.get('typeAnnotation')
.get('typeAnnotation');

expect(getFlowType(typePath)).toMatchSnapshot();
});
});
12 changes: 12 additions & 0 deletions src/utils/getFlowType.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ function handleObjectTypeAnnotation(
key: ((getPropertyName(param): any): string),
value: getFlowTypeWithRequirements(param.get('value'), typeParams),
});
} else if (t.ObjectTypeSpreadProperty.check(param.node)) {
let spreadObject = resolveToValue(param.get('argument'));
if (t.GenericTypeAnnotation.check(spreadObject.node)) {
const typeAlias = resolveToValue(spreadObject.get('id'));
if (t.ObjectTypeAnnotation.check(typeAlias.get('right').node)) {
spreadObject = resolveToValue(typeAlias.get('right'));
}
}
if (t.ObjectTypeAnnotation.check(spreadObject.node)) {
const props = handleObjectTypeAnnotation(spreadObject, typeParams);
type.signature.properties.push(...props.signature.properties);
}
}
});

Expand Down

0 comments on commit 4718d8b

Please sign in to comment.