This question has taken me some time to put down; I hope that I have explained my situation well. Please feel free to ask any questions. I don't really expect an answer to this question. Any hints or tips in which direction I should proceed would really help me out too :)
Abstract
How do I create a synthetic Type for a given object type?
Using this code as an example, I would replicate the process of converting this TypeLiteral:
{
member1: string,
member2: number
}
into the corresponding Type:
Type {
flags: 524288 // Object (2 ^ 19)
id: 79
objectFlags: 16 // Anonymous (2 ^ 4)
members:{
member1: Symbol (member1)
member2: Symbol (member2)
}
properties: [
Symbol (member1)
Symbol (member2)
]
callSignatures:[]
constructSignatures:[]
indexInfos:[]
aliasSymbol:undefined
aliasTypeArguments:undefined
}
Use case
Given the following code:
declare function query<R = {}>(q: string): Promise<R> // Do some database query stuff
query("query0");
query("query1");
query("query2");
I would like to dynamically replace the default type of R for each call of query.
I am pretty sure that I have already figured out where to insert my code, but am now stuck on creating my artificial Type.
Ideally, I could just call a function convertStructureToType that takes a json-like representation of the type I would like to represent and returns a readily baked Type (see above).
Where I am stuck
Proceeding checks whether type really is the function type whose default argument I would like to change, the following code provides me with {}, which is still missing properties, but it's some progress, albeit only little:
// ...
var type = getTypeOfSymbol(localOrExportSymbol);
if(shouldWeModify(localOrExportSymbol)) { // Check whether we are operating on the correct `query` identifier
var od = type.callSignatures[0].typeParameters[0].default;
var oldDefaultSymbol = type.callSignatures[0].typeParameters[0].default.symbol;
var propertiesTable = ts.createSymbolTable();
// Set default type structure
// propertiesTable.set("member1", ?); // Expects a symbol; what do I do
// propertiesTable.set("member2", ?);
// Put together new Type
var newDefaultType = createAnonymousType(oldDefaultSymbol, propertiesTable, ts.emptyArray, ts.emptyArray, ts.emptyArray);
newDefaultType.objectFlags |= 16;
// Set new custom default type
type.callSignatures[0].typeParameters[0].default = newDefaultType;
}
var assignmentKind = ts.getAssignmentTargetKind(node);
// ...
I have tried using createSymbol and the like, which results in some error along the lines "reading property .kind of undefined". If I understand the call stack correctly, this is due to .parent missing on some symbol, respectively the symbol not actually being member of a SourceFile.