Skip to content

Commit 9e53878

Browse files
authored
feat: support non-legal identifiers in field property names (#29)
* feat: support non-legal identifiers in field property names Quoted string literals are allowed to be field property names. This supports non-legal identifiers. Things like hyphenated field names.
1 parent 918fc1c commit 9e53878

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ func (ts *Typescript) buildStruct(obj types.Object, st *types.Struct) (*bindings
679679
// Use the json name if present
680680
jsonTag, err := tags.Get("json")
681681
if err == nil {
682-
if jsonTag.Name == "-" {
682+
if jsonTag.Name == "-" && len(jsonTag.Options) == 0 {
683683
// Completely ignore this field.
684684
continue
685685
}

testdata/nonids/nonids.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package nonids
2+
3+
type Foo struct {
4+
// Hyphen is an odd case, but this field is not ignored
5+
Hyphen string `json:"-,"`
6+
Ignored string `json:"-"`
7+
Hyphenated string `json:"hyphenated-string"`
8+
Numbered int `json:"1numbered"`
9+
}

testdata/nonids/nonids.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Code generated by 'guts'. DO NOT EDIT.
2+
3+
// From nonids/nonids.go
4+
export interface Foo {
5+
readonly "-": string;
6+
readonly "hyphenated-string": string;
7+
readonly "1numbered": number;
8+
}

typescript-engine/dist/main.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

typescript-engine/src/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// https://astexplorer.net/
1212

1313
import * as ts from "typescript";
14-
import { Modifier, ModifierSyntaxKind } from "typescript";
14+
import {Identifier, Modifier, ModifierSyntaxKind, StringLiteral} from "typescript";
1515

1616
type modifierKeys = FilterKeys<typeof ts.SyntaxKind, ModifierSyntaxKind>;
1717
export function modifier(name: modifierKeys | ts.Modifier): Modifier {
@@ -28,6 +28,7 @@ export function identifier(name: string | ts.Identifier): ts.Identifier {
2828
if (typeof name !== "string") {
2929
return name;
3030
}
31+
3132
return ts.factory.createIdentifier(name);
3233
}
3334

@@ -37,9 +38,20 @@ export function propertySignature(
3738
question: boolean,
3839
type: ts.TypeNode
3940
): ts.PropertySignature {
41+
42+
var id: Identifier | StringLiteral = identifier(name);
43+
44+
// Property names can be quoted if they are not valid identifiers.
45+
// This is things like hyphens, numbers first, etc.
46+
// TODO: If this regex exists in the typescript compiler, use that instead.
47+
if(!(/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name))) {
48+
id = ts.factory.createStringLiteral(name);
49+
}
50+
51+
4052
return ts.factory.createPropertySignature(
4153
modifiers?.map((m) => modifier(m)),
42-
identifier(name),
54+
id,
4355
question ? questionToken() : undefined,
4456
type
4557
);

0 commit comments

Comments
 (0)