@@ -66,3 +66,89 @@ export function getTextOfJsxAttributeName(node: ts.JsxAttributeName): string {
66
66
? ts . idText ( node )
67
67
: `${ ts . idText ( node . namespace ) } :${ ts . idText ( node . name ) } `
68
68
}
69
+
70
+ type ObjectLiteralElementWithName = ts . ObjectLiteralElement & {
71
+ name : ts . PropertyName
72
+ parent : ts . ObjectLiteralExpression | ts . JsxAttributes
73
+ }
74
+ export function getContainingObjectLiteralElement (
75
+ node : ts . Node
76
+ ) : ObjectLiteralElementWithName | undefined {
77
+ const element = getContainingObjectLiteralElementWorker ( node )
78
+ return element &&
79
+ ( ts . isObjectLiteralExpression ( element . parent ) ||
80
+ ts . isJsxAttributes ( element . parent ) )
81
+ ? ( element as ObjectLiteralElementWithName )
82
+ : undefined
83
+ }
84
+
85
+ function getContainingObjectLiteralElementWorker (
86
+ node : ts . Node
87
+ ) : ts . ObjectLiteralElement | undefined {
88
+ switch ( node . kind ) {
89
+ case ts . SyntaxKind . StringLiteral :
90
+ case ts . SyntaxKind . NoSubstitutionTemplateLiteral :
91
+ case ts . SyntaxKind . NumericLiteral : {
92
+ if ( node . parent . kind === ts . SyntaxKind . ComputedPropertyName ) {
93
+ return ts . isObjectLiteralElement ( node . parent . parent )
94
+ ? node . parent . parent
95
+ : undefined
96
+ }
97
+ // falls through
98
+ }
99
+
100
+ case ts . SyntaxKind . Identifier : {
101
+ return ts . isObjectLiteralElement ( node . parent ) &&
102
+ ( node . parent . parent . kind === ts . SyntaxKind . ObjectLiteralExpression ||
103
+ node . parent . parent . kind === ts . SyntaxKind . JsxAttributes ) &&
104
+ node . parent . name === node
105
+ ? node . parent
106
+ : undefined
107
+ }
108
+ }
109
+ return undefined
110
+ }
111
+
112
+ export function getPropertySymbolFromContextualType (
113
+ node : ObjectLiteralElementWithName ,
114
+ contextualType : ts . Type
115
+ ) : ts . Symbol | undefined {
116
+ const name = getNameFromPropertyName ( node . name )
117
+ if ( ! name ) {
118
+ return undefined
119
+ }
120
+ return contextualType . getProperty ( name )
121
+ }
122
+
123
+ export function getNameFromPropertyName (
124
+ name : ts . PropertyName
125
+ ) : string | undefined {
126
+ return name . kind === ts . SyntaxKind . ComputedPropertyName
127
+ ? // treat computed property names where expression is string/numeric literal as just string/numeric literal
128
+ isStringOrNumericLiteralLike ( name . expression )
129
+ ? name . expression . text
130
+ : undefined
131
+ : ts . isPrivateIdentifier ( name )
132
+ ? ts . idText ( name )
133
+ : getTextOfIdentifierOrLiteral ( name )
134
+ }
135
+
136
+ export function isStringOrNumericLiteralLike (
137
+ node : ts . Node
138
+ ) : node is ts . StringLiteralLike | ts . NumericLiteral {
139
+ return ts . isStringLiteralLike ( node ) || ts . isNumericLiteral ( node )
140
+ }
141
+
142
+ export function getTextOfIdentifierOrLiteral (
143
+ node : ts . PropertyNameLiteral | ts . PrivateIdentifier
144
+ ) : string {
145
+ return ts . isMemberName ( node )
146
+ ? ts . idText ( node )
147
+ : ts . isJsxNamespacedName ( node )
148
+ ? getTextOfJsxNamespacedName ( node )
149
+ : node . text
150
+ }
151
+
152
+ export function getTextOfJsxNamespacedName ( node : ts . JsxNamespacedName ) : string {
153
+ return `${ ts . idText ( node . namespace ) } :${ ts . idText ( node . name ) } `
154
+ }
0 commit comments