Eksport av symboldklarering i TypeScript
I et prosjekt jeg jobber med, bruker jeg symboler for å merke funksjoner for å avgjøre om koden skal bruke funksjonsuttrykket selv eller kalle det og bruke den returnerte verdien. For øyeblikket ser det slik ut:
const shouldEvaluate: unique symbol = Symbol('evaluate');
interface FlaggableFunction extends Function {
[shouldEvaluate]?: boolean
}
Selv om dette fungerer, når jeg aktiverer deklarasjoner i konfigurasjonen min, får jeg feilen semantic error TS4033 Property '[shouldEvaluate]' of exported interface has or is using private name 'shouldEvaluate'.. Det fungerer hvis jeg eksporterer dette symbolet, men det blir også eksportert til den kompilerte JS-en, noe jeg ikke ønsker. Finnes det en måte å eksportere et symbol bare til deklarasjonsfilen samtidig som det holdes privat i den kompilerte JS-en?
Så langt har jeg prøvd å erklære typen og initialisere variabelen separat
export declare let shouldEvaluate: unique symbol;
shouldEvaluate = Symbol('evaluate');
men dette gir meg en feil om at et unikt symbol må erklæres med const. Jeg prøvde også å gi FlaggableFunction i indeks-signaturen slik:
interface FlaggableFunction extends Function {
[key: unique symbol]: boolean
}
men det gir TS1023 En indeksignatur parameter type må være 'string' eller 'number'.
Svar #1
Finnes det en måte å eksportere et symbol bare til deklarasjonsfilen samtidig som det holdes privat i den kompilerte JS-filen?
Når du gjør export declare let shouldEvaluate: unique symbol; blir det offentlig uansett.
Så nei, du kan ikke bruke en privat variabel som er en del av en offentlig type.
Du kan holde alt privat. Men det er ikke det du vil.
Svar #2
Oppdatering: Jeg innså at jeg enkelt kunne ha flyttet flaggene til en egen fil og eksportert dem, siden jeg i min situasjon var mer opptatt av å beholde en enkelt standardeksport i inngangsfilen enn jeg var av å eksponere flaggene. Nedenfor var mitt tidligere forsøk, som var litt av et rot.
Det tok litt arbeid, men jeg har kommet fram til en løsning som på en måte fungerer. I hovedsak flyttet jeg alle kodereferanser til disse symbolene ut i egne private funksjoner, og bruker et objektliteral for å mappe til disse symbolene.
const shouldEvaluate: unique symbol = Symbol('evaluate');
const flags: { [key: string]: symbol } = {
evaluate: shouldEvaluate
};
// Switched to a single Flaggable type that takes a generic type instead of creating multiple so it an be passed into the setFlag function
export type Flaggable<T> = T & {
[shouldEvaluate]?: boolean
}
function setFlag(val: Flaggable<any>, flag: string) {
const symbol: symbol = flags[flag];
val[symbol] = true;
}
Så nå, i den eksporterte klassen, i stedet for å sette symbolet som en egenskap på funksjonen direkte, bruker jeg setFlag-funksjonen.
export default class MyClass {
setEvalFlag (func: Flaggable<Function>): Flaggable<Function> {
setFlag(func, 'evaluate');
return func;
}
}
