Skip to content

Commit

Permalink
fix(api): error getting signature type arguments
Browse files Browse the repository at this point in the history
closes #14
  • Loading branch information
mxsdev committed Nov 6, 2022
1 parent 1103cc0 commit 732fe0d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 39 deletions.
6 changes: 6 additions & 0 deletions packages/api/src/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { TypescriptContext } from "./types"
*/
export type SymbolName = ts.__String

/**
* @internal
*/
type TypeMapper = unknown

/**
* @internal
*/
Expand Down Expand Up @@ -112,6 +117,7 @@ export type SignatureInternal = ts.Signature & {
minArgumentCount: number
resolvedMinArgumentCount?: number
target?: SignatureInternal
mapper: TypeMapper
}
/**
* @internal
Expand Down
57 changes: 22 additions & 35 deletions packages/api/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import assert = require("assert")
import * as ts from "typescript"
import {
wrapSafe,
Expand Down Expand Up @@ -437,34 +438,12 @@ export function isObjectReference(
return !!(getObjectFlags(ctx, type) & ts.ObjectFlags.Reference)
}

type Mutable<T> = { -readonly [k in keyof T]: T[k] }

export function getTypeFromTypeNode(
{ ts, typeChecker }: TypescriptContext,
{ typeChecker }: TypescriptContext,
node: ts.TypeNode,
enclosingDeclaration?: ts.Node
) {
if (!(node.flags & ts.NodeFlags.Synthesized)) {
return typeChecker.getTypeFromTypeNode(node)
} else {
node = cloneClassInstance(node)

if (ts.isTypeReferenceNode(node)) {
if (node.typeName && enclosingDeclaration) {
;(node as Mutable<ts.TypeReferenceNode>).typeName =
cloneClassInstance(node.typeName)
;(node.typeName as Mutable<ts.EntityName>).parent ??=
enclosingDeclaration
}
}

;(node as Mutable<ts.TypeNode>).flags &= ~ts.NodeFlags.Synthesized
;(node as Mutable<ts.TypeNode>).parent ??= {
kind: ts.SyntaxKind.VariableStatement,
} as ts.Node

return typeChecker.getTypeFromTypeNode(node)
}
return typeChecker.getTypeFromTypeNode(node)
}

export function getTypeArguments<T extends ts.Type>(
Expand Down Expand Up @@ -723,19 +702,27 @@ export function getSignatureTypeArguments(
ctx: TypescriptContext,
signature: ts.Signature,
enclosingDeclaration?: ts.Node
) {
): readonly ts.Type[] {
const { typeChecker, ts } = ctx

return typeChecker
.signatureToSignatureDeclaration(
signature,
ts.SyntaxKind.CallSignature,
enclosingDeclaration,
ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature
)
?.typeArguments?.map((t) =>
getTypeFromTypeNode(ctx, t, enclosingDeclaration)
) // TODO: error here...
const target = (signature as SignatureInternal).target

if (!target) {
return []
}

// workaround to force instantiation of signature type arguments
return typeChecker.getTypeArguments({
node: {
kind: ts.SyntaxKind.TypeReference,
},
target: {
outerTypeParameters: target.typeParameters ?? [],
localTypeParameters: [],
},
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
mapper: (signature as SignatureInternal).mapper,
} as unknown as ts.TypeReference)
}

export function getDescendantAtPosition(
Expand Down
27 changes: 23 additions & 4 deletions tests/other/map.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ describe("map.ts", () => {
it("doesn't error when retrieving outside", () => {
const ctx = createTsContext(fileName)

const pos = {
line: 5,
character: 0,
}
const pos = { line: 5, character: 0 }

getTypeInfoAtRange(
ctx,
Expand All @@ -27,3 +24,25 @@ describe("map.ts", () => {
)
})
})

const fileName2 = path.join(__dirname, "map2.ts")

describe("map2.ts", () => {
it("deosn't error when retrieving outside", () => {
const ctx = createTsContext(fileName2)

const pos = { line: 3, character: 0 }

getTypeInfoAtRange(
ctx,
{
fileName: fileName2,
range: {
start: pos,
end: pos,
},
},
apiConfig
)
})
})
4 changes: 4 additions & 0 deletions tests/other/map2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as ts from "typescript"
;([] as unknown as ts.NodeArray<ts.TypeNode>).map(
(x) => x as unknown as ts.Type
)

0 comments on commit 732fe0d

Please sign in to comment.