I am trying to build a generic function that performs the type-dependent symbol lookup.
The shortened version of the example is as follows:
type Symbol = TypeDef | VarDecl
interface TypeDef
{
kind: 'type',
name: string,
typeData: string;
}
interface VarDecl
{
kind: 'var',
name: string,
varData: number
}
type SymbolKind = Symbol['kind'];
interface SymbolMap
{
type: TypeDef[],
var: VarDecl[]
}
Now I need a generic type-safe symbol lookup function.
If I make SymbolKind the function argument, then I can’t narrow down the function result type:
function LookupSymbol(kind: SymbolKind, map: SymbolMap, name: string)
{
let symbols = map[kind];
for(var symbol of symbols)
{
if(symbol.name == name)
return symbol;
}
}
let x = LookupSymbol('var', m, 'x'); // x: TypeDef | VarDecl | undefined
If I make the symbol type a generic argument, then I can’t select the map property:
interface SymbolBase
{
kind: SymbolKind,
name: string
}
function LookupSymbol2<T extends SymbolBase>(map: SymbolMap, name: string): T | undefined
{
let symbols = map[???];
for(var symbol of symbols)
{
if(symbol.name == name)
return symbol;
}
return undefined;
}
Is there a way to write down this in TypeScript, so I can get either a
LookupSymbol<VarDecl>(SymbolMap map, string name): VarDecl | undefined
or
LookupSymbol(SymbolMap map, 'var', string name): VarDecl | undefined
?
Tried to use Extract<> generic type as the function return type in option 1 – doesn’t work, as it needs a type or const, instead of a parameter.
Tried to extract the kind from the generic type parameter – but couldn’t find a way to do it.
Антон Игоревич Злыгостев is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.