在我正在研究的项目中,我使用符号来标记函数以确定代码是应该使用函数表达式本身还是调用它并使用返回的值。目前它看起来像这样:
const shouldEvaluate: unique symbol = Symbol('evaluate');
interface FlaggableFunction extends Function {
[shouldEvaluate]?: boolean
}
虽然这有效,但当我在配置中启用声明时,我收到错误semantic error TS4033 Property '[shouldEvaluate]' of exported interface has or is using private name 'shouldEvaluate'.
。它可以导出这个符号,但它也会导出到编译的JS,我不想要。有没有办法只将符号导出到声明文件,同时在编译的JS中保持私有?
到目前为止,我已尝试声明类型并单独启动变量
export declare let shouldEvaluate: unique symbol;
shouldEvaluate = Symbol('evaluate');
但是这给了我一个错误,即必须使用const声明一个唯一的符号。我还尝试在索引签名中给出FlaggableFunction
,如下所示:
interface FlaggableFunction extends Function {
[key: unique symbol]: boolean
}
但是会引发TS1023 An index signature parameter type must be 'string' or 'number'.
答案 0 :(得分:2)
是否有一种方法只将符号导出到声明文件,同时在编译的JS中保持私有?
当你做export declare let shouldEvaluate: unique symbol;
时它会变得公开。
所以不,你不能使用属于公共类型的私有变量。
您可以保持一切私密。但那不是你想要的。
答案 1 :(得分:1)
更新:我意识到我可以很容易地将标志移动到一个单独的文件中并导出它们,因为在我的情况下我更关心的是在条目文件中保留一个默认导出而不是我揭露旗帜。以下是我之前的尝试,这有点乱。
这需要一些工作,但我已经找到了一种有效的解决方案。基本上,我将所有对外部符号的引用移动到它们自己的私有函数中,并使用对象文字映射到这些符号。
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;
}
现在在导出的类中,不是直接将符号设置为函数的属性,而是使用setFlag函数。
export default class MyClass {
setEvalFlag (func: Flaggable<Function>): Flaggable<Function> {
setFlag(func, 'evaluate');
return func;
}
}