-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(indexedAccess): add indexed access support for mocks (#119)
* feat(indexedAccess): add indexed access support for mocks * update documentation
- Loading branch information
Showing
6 changed files
with
122 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import * as ts from 'typescript'; | ||
import { TransformerLogger } from '../../logger/transformerLogger'; | ||
import { Scope } from '../../scope/scope'; | ||
import { TypeChecker } from '../../typeChecker/typeChecker'; | ||
import { GetDescriptor } from '../descriptor'; | ||
import { TypescriptHelper } from '../helper/helper'; | ||
import { GetNullDescriptor } from '../null/null'; | ||
import { PropertySignatureCache } from '../property/cache'; | ||
|
||
export function GetIndexedAccessTypeDescriptor(node: ts.IndexedAccessTypeNode, scope: Scope): ts.Expression { | ||
const typeChecker: ts.TypeChecker = TypeChecker(); | ||
let propertyName: string | null = null; | ||
|
||
switch (node.indexType.kind) { | ||
case ts.SyntaxKind.TypeReference: | ||
const declaration: ts.Declaration = TypescriptHelper.GetDeclarationFromNode((node.indexType as ts.TypeReferenceNode).typeName); | ||
|
||
switch (declaration.kind) { | ||
case ts.SyntaxKind.TypeParameter: | ||
const propertyNameIdentifier: ts.PropertyName = PropertySignatureCache.instance.get(); | ||
propertyName = (propertyNameIdentifier as ts.Identifier).escapedText as string; | ||
break; | ||
case ts.SyntaxKind.TypeAliasDeclaration: | ||
propertyName = (((declaration as ts.TypeAliasDeclaration).type as ts.LiteralTypeNode).literal as ts.StringLiteral).text; | ||
break; | ||
default: | ||
TransformerLogger().typeNotSupported('IndexedAccess of TypeReference of ' + ts.SyntaxKind[declaration.kind]); | ||
break; | ||
} | ||
break; | ||
case ts.SyntaxKind.LiteralType: | ||
propertyName = ((node.indexType as ts.LiteralTypeNode).literal as ts.StringLiteral).text; | ||
break; | ||
default: | ||
TransformerLogger().typeNotSupported('IndexedAccess of ' + ts.SyntaxKind[node.indexType.kind]); | ||
break; | ||
} | ||
|
||
if (propertyName !== null) { | ||
const propertySymbol: ts.Symbol = typeChecker.getPropertyOfType(typeChecker.getTypeFromTypeNode(node.objectType), propertyName); | ||
return GetDescriptor(TypescriptHelper.GetDeclarationFromSymbol(propertySymbol), scope); | ||
} | ||
|
||
return GetNullDescriptor(); | ||
} |
62 changes: 62 additions & 0 deletions
62
test/transformer/descriptor/indexedAccess/indexedAccess.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { createMock } from 'ts-auto-mock'; | ||
import { Interface } from '../utils/interfaces/basic'; | ||
import { LiteralA } from '../utils/types/literals'; | ||
|
||
describe('indexedAccess', () => { | ||
interface A { | ||
a: string; | ||
b: number; | ||
} | ||
|
||
it('should work with key in keyof', () => { | ||
type AType = {[key in keyof A]: A[key]}; | ||
const mock: AType = createMock<AType>(); | ||
expect(mock.a).toEqual(''); | ||
expect(mock.b).toEqual(0); | ||
}); | ||
|
||
it('should work with key in literal', () => { | ||
type AType = {[key in 'a']: A[key]}; | ||
const mock: AType = createMock<AType>(); | ||
expect(mock.a).toEqual(''); | ||
expect((mock as any).b).toBeUndefined(); | ||
}); | ||
|
||
it('should work with key in keyof with literal index', () => { | ||
type AType = {[key in keyof A]: A['b']}; | ||
const mock: AType = createMock<AType>(); | ||
expect(mock.a).toEqual(0); | ||
expect(mock.b).toEqual(0); | ||
}); | ||
|
||
it('should work with key in keyof with imported literal index', () => { | ||
type AType = {[key in keyof A]: A[LiteralA]}; | ||
const mock: AType = createMock<AType>(); | ||
expect(mock.a).toEqual(''); | ||
expect(mock.b).toEqual(''); | ||
}); | ||
|
||
it('should work with key in keyof with imported interface and literal index', () => { | ||
type AType = {[key in keyof Interface]: Interface[LiteralA]}; | ||
const mock: AType = createMock<AType>(); | ||
expect(mock.a).toEqual(''); | ||
expect(mock.b).toEqual(''); | ||
}); | ||
|
||
it('should work with key in keyof with interface having complex properties', () => { | ||
interface InterfaceWithComplex { | ||
a: A; | ||
b: string; | ||
c: InterfaceWithComplex; | ||
} | ||
|
||
type InterfaceType = {[key in keyof InterfaceWithComplex]: InterfaceWithComplex[key]}; | ||
const mock: InterfaceType = createMock<InterfaceType>(); | ||
expect(mock.a.a).toEqual(''); | ||
expect(mock.a.b).toEqual(0); | ||
expect(mock.b).toEqual(''); | ||
expect(mock.c.a.a).toEqual(''); | ||
expect(mock.c.a.b).toEqual(0); | ||
expect(mock.c.b).toEqual(''); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type LiteralA = 'a'; |