В моем проекте у меня есть класс, который действует как универсальный тип для файлов.В зависимости от того, какой тип файла мы обрабатываем, он должен предоставлять дополнительные свойства.
Я пытался добиться этого с помощью условных типов, которые по умолчанию имеют значение never
, чтобы «скрыть» свойство.Однако, когда я пытаюсь использовать этот класс, средство проверки типов жалуется, что мне не хватает свойства, которое было выведено как тип never
.Конечно, я не могу назначить его, поэтому у меня остался объект, который невозможно создать.
Ошибка происходит полностью внизу этого блока кода:
// just for convenience
type MP4OptionsT = {
codec?: 'h264',
profile: 'baseline' | 'main' | 'high',
bitrate: number,
};
// this is the class in question
class MediaFile<Format extends 'mp4' | 'png'> {
public path: string;
public format: Format extends 'mp4' ? 'mp4' : Format extends 'png' ? 'png' : never; // once the generic type argument is set, this can only be a specific string literal
// this should not have to be assigned if generic type argument is 'png'
public mp4Options: Format extends 'mp4' ? MP4OptionsT : never;
constructor(opts: {
path: string,
format: Format extends 'mp4' ? 'mp4' : Format extends 'png' ? 'png' : never;
// this should not have to be assigned if generic type argument is 'png' - however it demands to be assigned
mp4Options: Format extends 'mp4' ? MP4OptionsT : never,
}) {
this.path = opts.path;
this.format = opts.format;
this.mp4Options = opts.mp4Options;
}
}
// this is OK
const mp4File = new MediaFile<'mp4'>({
path: '/some/file/somewhere.mp4',
format: 'mp4',
mp4Options: {
profile: 'high',
bitrate: 1000,
}
});
// the type checker complains about this: "Property mp4Otions is missing in type {...}".
// if I explicitly include mp4Options, the type checker notes that "Type any is not assignable to Type never" - which makes sense, but precludes this class from ever being instantiated.
const pngFile = new MediaFile<'png'>({
path: '/some/file/somewhere.png',
format: 'png', // since there is exactly one option for this, it would be nice if it were implicitly set...
});
Из моего понимания раздела Условные типы этой страницы http://www.typescriptlang.org/docs/handbook/advanced-types.html кажется, что mp4Options просто должен быть в состоянии "не там", если он был оценен как тип never
.В качестве эксперимента я также попытался вернуть его к неопределенному.Это сработало, если я вручную назначил mp4Options: undefined
, в противном случае средство проверки типов по-прежнему жаловалось на отсутствие свойств.Я думаю, что это определенно не должно иметь место, поскольку мы можем опустить свойства, которые undefined
из коробки (без условного типа).
Есть ли обходной путь или менее запутанный способ сделать это?Или у меня просто ошибка в моем коде?