我有这个TS代码:
type DefaultLevel = 'info' | 'error'; // Default log levels
interface LoggerOptions<CustomLevels extends string, Level extends CustomLevels | DefaultLevel> {
customLevels?: Record<CustomLevels, number>
level: Level
}
class Logger<CustomLevel extends string = '', Level extends CustomLevel | DefaultLevel = CustomLevel | DefaultLevel> {
constructor(options?: LoggerOptions<CustomLevel, Level>) {
// Initialization based on options
}
log(level: Level, message: string) {
// Log message
}
}
// Usage
const logger = new Logger({
customLevels: {
debug: 1,
trace: 2,
},
level: 'debug'
});
logger.log('debug', '')
我首先为我的记录器创建了一个全局DefaultLevel
union
type
.然后我有一个LoggerOption
接口,它有两个泛型CustomLevels
和Level
.CustomLevels
允许我为我的记录器创建自定义级别,以确保所有类型的安全,而Level extends CustomLevels | DefaultLevels
是为我的默认记录器设置默认级别所必需的.执行level: CustomLevels
操作不起作用,因此出现了第二个泛型.
我的问题出现在类的log函数中.
如果我try 调用logger. log('trace'),我会得到一个类型错误:'type'"tracess"'的参数不能赋值给type'"调试"的参数."
因此,我认为LoggerOptions
接口正在设置Level
类型值.
我的问题是,为什么在LoggerOptions
中,级别可以是类型'info' | 'error' | 'debug' | 'trace'
(所需的行为),而在后面的代码中,类型Level
的变量只能是在LoggerOptions
中设置的字符串类型?
我知道在log()方法中,我可以做这样的事情:
log(level: CustomLevel | DefaultLevel, message: string) {
// Log message
}
但使用Level
型肯定会更整洁.