blob: b7d4efea24a84244e64af65bf89876ce9e92efa3 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
import { SyntaxKind, Type } from 'ts-morph'
import { Ctx } from './types'
export const match = <K extends string, R>(
k: K | undefined,
pattern: { [key in K | '_']: () => R }
) => (k && pattern[k] ? pattern[k]() : pattern._())
export const evalList = async (ctx: Ctx, effectTyps: Type[]) => {
const effectResults: (string | undefined)[] = []
for (const item of effectTyps ?? []) {
const [resultKey] = await ctx.evaluateType(ctx, item)
effectResults.push(resultKey ? resultKey : undefined)
}
return effectResults
}
export const applyFunc = (
ctx: Ctx,
fn: Type | undefined,
val: string
): Type => {
const resultType = (() => {
const baseTypes = fn
?.getBaseTypes()
.flatMap((t) => t.getSymbol()?.getName() ?? [])
if (!!fn?.getProperty('return') || baseTypes?.includes('Kind1')) {
const [key, resultNode] = ctx.createResult(
`(${ctx.typeToString(fn)} & { input: ${val} })['return']`
)
ctx.removeResult(key)
return resultNode
?.getType()
.getProperty('output')
?.getTypeAtLocation(resultNode)
} else {
const [key, resultNode] = ctx.createResult(
`ReturnType<${ctx.typeToString(fn)}>`
)
ctx.removeResult(key)
const resValueNode = resultNode
?.asKind(SyntaxKind.PropertySignature)
?.getChildAtIndexIfKind(2, SyntaxKind.TypeLiteral)
?.getProperty('output')
?.getChildAtIndexIfKind(2, SyntaxKind.TypeReference)
const functionNode = resValueNode
?.getChildAtIndexIfKind(1, SyntaxKind.SyntaxList)
?.getFirstChildIfKind(SyntaxKind.FunctionType)
if (functionNode) {
const typeParameters = functionNode.getTypeParameters() ?? []
if (typeParameters.length > 0) {
const constraint = typeParameters[0]?.getConstraint()
if (constraint) {
constraint?.replaceWithText(val)
} else {
typeParameters[0]?.setConstraint(val)
}
}
return resValueNode?.getType()
}
}
return undefined
})()
if (!resultType) {
throw new Error('Couldnt get result for function application')
}
return resultType
}
|