Typescript tsc.js create artificial type literal type

Viewed 45

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.

0 Answers
Related