Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a94aa34

Browse files
feat: enhance PhpDocTypeNodeToTypescriptTypeNodeTranspiler with importName and typeIdentifiers
- Added importName and typeIdentifiers to the nameNodePathResolver return type. - Updated logic to handle external types and generate import statements accordingly. - Improved type reference creation to support qualified names for multiple identifiers.
1 parent f0c5bef commit a94aa34

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

‎_typos.toml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[default.extend-words]
22
Ue = "Ue"
33
ND = "ND"
4-
ba = "ba"
4+
ba = "ba"
5+
ede = "ede"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "feat: enhance PhpDocTypeNodeToTypescriptTypeNodeTranspiler with importName and typeIdentifiers",
4+
"packageName": "@rightcapital/phpdoc-parser",
5+
"email": "yilunsun11@yeah.net",
6+
"dependentChangeType": "patch"
7+
}

‎src/phpdoc-parser/transpiler/php-doc-to-typescript-type-transpiler.ts‎

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
factory,
3+
type Identifier,
34
type ImportDeclaration,
5+
type QualifiedName,
46
SyntaxKind,
57
type TypeNode,
68
} from 'typescript';
@@ -18,16 +20,18 @@ export type NameNodePathResolver<T> = (
1820
nodeParts: string[],
1921
) => {
2022
path: string;
21-
name: string;
23+
importName: string;
2224
isTypeOnly: boolean;
25+
typeIdentifiers: string[];
2326
};
2427

2528
export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
2629
constructor(
2730
public nameNodePathResolver: (nodeParts: string[]) => {
2831
path: string;
29-
name: string;
32+
importName: string;
3033
isTypeOnly: boolean;
34+
typeIdentifiers: string[];
3135
},
3236
) {}
3337

@@ -87,6 +91,7 @@ export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
8791
'non-empty-array',
8892
'list',
8993
'non-empty-list',
94+
'\\Illuminate\\Support\\Collection',
9095
'\\Illuminate\\Database\\Eloquent\\Collection',
9196
].includes(sourceTypeNode.type.name)
9297
) {
@@ -167,7 +172,11 @@ export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
167172
return factory.createToken(SyntaxKind.VoidKeyword);
168173
}
169174

170-
if (sourceTypeNode.name === 'null') {
175+
if (
176+
['\\Illuminate\\Http\\Resources\\MissingValue', 'null'].includes(
177+
sourceTypeNode.name,
178+
)
179+
) {
171180
return factory.createLiteralTypeNode(factory.createNull());
172181
}
173182

@@ -179,10 +188,11 @@ export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
179188
if (/^[A-Z\\]/.test(sourceTypeNode.name)) {
180189
const nameNodeParts = sourceTypeNode.name.split('\\');
181190

182-
const { name,path, isTypeOnly } =
191+
const { path, isTypeOnly, importName, typeIdentifiers } =
183192
this.nameNodePathResolver(nameNodeParts);
184193

185-
if (name !== 'string' && path !== '') {
194+
// For external types, generate import statement
195+
if (importName !== 'string' && path !== '') {
186196
this.importDeclarations.push(
187197
factory.createImportDeclaration(
188198
undefined,
@@ -193,7 +203,7 @@ export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
193203
factory.createImportSpecifier(
194204
false,
195205
undefined,
196-
factory.createIdentifier(name),
206+
factory.createIdentifier(importName),
197207
),
198208
]),
199209
),
@@ -203,10 +213,30 @@ export class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
203213
);
204214
}
205215

206-
returnfactory.createTypeReferenceNode(
207-
factory.createIdentifier(name),
208-
undefined,
216+
// Build qualified name recursively for multiple identifiers
217+
lettypeNameNode: QualifiedName|Identifier=factory.createIdentifier(
218+
typeIdentifiers[0],
209219
);
220+
221+
// typeIdentifiers = ['RestaurantNamespace', 'IPizza']
222+
// factory.createQualifiedName(
223+
// factory.createIdentifier("RestaurantNamespace"),
224+
// factory.createIdentifier("IPizza")
225+
// )
226+
// ⬇️
227+
// export interface IMyOrder {
228+
// ...
229+
// pizza: RestaurantNamespace.IPizza;
230+
// ...
231+
// }
232+
for (let i = 1; i < typeIdentifiers.length; i += 1) {
233+
typeNameNode = factory.createQualifiedName(
234+
typeNameNode,
235+
factory.createIdentifier(typeIdentifiers[i]),
236+
);
237+
}
238+
239+
return factory.createTypeReferenceNode(typeNameNode, undefined);
210240
}
211241
}
212242

‎tests/transpiler/transpiler.test.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class ExtendedTranspiler extends PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
1818
(nodeParts: string[]) =>
1919
resolver.call(this, nodeParts) as {
2020
path: string;
21-
name: string;
21+
importName: string;
22+
typeIdentifiers: string[];
2223
isTypeOnly: boolean;
2324
},
2425
);
@@ -49,10 +50,13 @@ const getPropertyTagValueNodesFromComment = (commentText: string) => {
4950
const nameNodePathResolver: NameNodePathResolver<ExtendedTranspiler> =
5051
// eslint-disable-next-line func-names
5152
function (this: ExtendedTranspiler, nodeParts: string[]) {
53+
const lastPart = nodeParts.at(-1);
54+
5255
return {
53-
name: nodeParts.at(-1),
5456
path: '',
5557
isTypeOnly: false,
58+
importName: lastPart,
59+
typeIdentifiers: [lastPart],
5660
};
5761
};
5862

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /