Skip to content

Commit f5866b0

Browse files
authored
Add typescript support for quoted keys in types (#188)
* Add typescript support for quoted keys in types * docs(changeset): Allow proper conversion of keys in TypeScript types that are quoted. * Fix test * Better test, more reflective of use case * Clearer changeset message * Add test for type Co-authored-by: Declan Warn <[email protected]>
1 parent 610f5e2 commit f5866b0

File tree

4 files changed

+59
-6
lines changed

4 files changed

+59
-6
lines changed

.changeset/seven-laws-deliver.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'extract-react-types': patch
3+
---
4+
5+
Adds support for string type keys in TypeScript.

packages/extract-react-types/converters-typescript.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -690,3 +690,33 @@ cases(
690690
},
691691
TESTS
692692
);
693+
694+
test('Typescript interface quoted property name is converted properly', () => {
695+
const name = 'quoted';
696+
const code = stripIndent(`
697+
interface Props {
698+
/* Type comment for ${name} */
699+
'${name}': string;
700+
}
701+
702+
class Component extends React.Component<Props> {}`);
703+
const typeSystem = 'typescript';
704+
const result = extractReactTypes(code, typeSystem, __filename);
705+
706+
expect(result).toHaveProperty(['component', 'value', 'members', 0, 'key', 'name'], name);
707+
});
708+
709+
test('Typescript type quoted property name is converted properly', () => {
710+
const name = 'quoted';
711+
const code = stripIndent(`
712+
type Props = {
713+
/* Type comment for ${name} */
714+
'${name}': string;
715+
}
716+
717+
class Component extends React.Component<Props> {}`);
718+
const typeSystem = 'typescript';
719+
const result = extractReactTypes(code, typeSystem, __filename);
720+
721+
expect(result).toHaveProperty(['component', 'value', 'members', 0, 'key', 'name'], name);
722+
});

packages/extract-react-types/src/converter.js

+22-6
Original file line numberDiff line numberDiff line change
@@ -535,12 +535,28 @@ converters.TSTypeLiteral = (path, context): K.Obj => ({
535535
members: path.get('members').map(memberPath => convert(memberPath, context))
536536
});
537537

538-
converters.TSPropertySignature = (path, context): K.Property => ({
539-
kind: 'property',
540-
optional: !!path.node.optional,
541-
key: { kind: 'id', name: path.node.key.name },
542-
value: convert(path.get('typeAnnotation'), context)
543-
});
538+
converters.TSPropertySignature = (path, context): K.Property => {
539+
let key = { kind: 'id' };
540+
switch (path.node.key.type) {
541+
case 'Identifier':
542+
key.name = path.node.key.name;
543+
break;
544+
545+
case 'StringLiteral':
546+
key.name = path.node.key.value;
547+
break;
548+
549+
default:
550+
key.name = undefined;
551+
}
552+
553+
return {
554+
kind: 'property',
555+
optional: !!path.node.optional,
556+
key,
557+
value: convert(path.get('typeAnnotation'), context)
558+
};
559+
};
544560

545561
converters.TSTypeAliasDeclaration = (path, context): K.Obj =>
546562
convert(path.get('typeAnnotation'), context);

stories/TypeScriptComponent.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ type TypeScriptComponentProps = {
3434
unknownProp: unknown;
3535
// This prop uses an unknown typescript keyword "keyof" and so will result in a bail-out
3636
unsupportedProp: keyof DummyInterface;
37+
// This prop uses hyphens, so the type uses quotations around the key
38+
'quoted-prop': any;
3739
};
3840

3941
const TypeScriptComponent = (props: TypeScriptComponentProps) => <p>Hello World</p>;

0 commit comments

Comments
 (0)