#typescript
Вопрос:
У меня есть тип SecretString
, который может содержать любую конфиденциальную информацию, которую я могу обрабатывать на своем сервере, но из которой я не хочу случайно выходить. Это фирменный строковый тип:
type SecretString = string amp; {__brand: "secret"}
Моя функция ведения журнала принимает строку и объект ( any
в настоящее время), который может содержать любую дополнительную информацию, которая может потребоваться. Есть ли у меня способ выразить этот второй параметр как тип, который может быть произвольным объектом, но будет жаловаться, если a SecretString
присутствует? Вложенная проверка была бы отличной, но я был бы доволен первым уровнем.
Поскольку SecretString
он работает так же, как строка, он обычно исходит из такой функции, как эта:
function decryptString(encryptedString: EncryptedString): SecretString {
// ...
}
Итак, это пример сценария, в котором я хотел бы получить сообщение об ошибке:
const keys = decryptString(encryptedKeys);
logger.info('This should not compile!', {
valueThatIsOk: 'this is ok',
valueThatShouldFail: keys
});
Ответ №1:
Рекурсивно в настоящее время выходит за рамки моего машинописного текста, но на верхнем уровне сопоставленный тип должен работать:
type SecretString = string amp; {__brand: "secret"};
function log<ObjType>(msg: any, obj: ObjType extends SecretString ? never : ObjType) {
console.log(msg, obj);
}
let x: SecretString = "example" as SecretString;
log("hi", {example: 42});
log("hi", "more info");
log("hi", x);
// ^−−−−−−−−−−−−−−− error as desired
Для передачи объекта вместо этого это все то же самое, но в структуре объекта:
function log<ObjType extends object>(
msg: any,
obj: {[key in keyof ObjType]: ObjType[key] extends SecretString ? never : ObjType[key]}
) {
console.log(msg, obj);
}
(Если вы хотите и то, и другое, вы можете объединить их в союз.)
Комментарии:
1. Я ценю это, но это всего лишь один уровень «сверху» 🙂 Хотя строки и другие примитивные значения разрешены в качестве второго параметра, я всегда передаю объект. Поэтому, когда я сказал, что вложенность не нужна, я имел в виду за пределами этого уровня.
2. @KristianDupont — Я добавил пример, который обрабатывает объект и ваш пример вызова.