I have an interface like below
export type CameraProps = Omit<React.HTMLProps<HTMLVideoElement>, "ref"> & {
audio?: boolean;
audioConstraints?: MediaStreamConstraints["audio"];
mirrored?: boolean;
screenshotFormat?: "image/webp" | "image/png" | "image/jpeg";
//between 0 & 1
screenshotQuality?: number;
videoConstraints?: MediaStreamConstraints["video"];
fullScreenRecord?: boolean;
screenshotDimensions?: ScreenshotDimensions;
setImageSrc?: Dispatch<SetStateAction<string>>;
overlay?: boolean;
}
when I use pick to pick one of this property like this
private videoConstraints: Pick<CameraProps, 'videoConstraints'>;
I got this error in this line of my code
this.videoConstraints = videoConstraints;
Type  boolean | MediaTrackConstraints | undefined is not assignable to type  Pick<CameraProps, "videoConstraints">Â
Type  undefined is not assignable to type  Pick<CameraProps, "videoConstraints">Â
it seems pick remove undefined from my type but when I write the code like below
private videoConstraints: CameraProps['videoConstraints'];
every thing is fine
The full code is like below
import React, {Dispatch, SetStateAction} from "react";
export type ScreenshotDimensions = {
width: number;
height: number;
}
export type CameraProps = Omit<React.HTMLProps<HTMLVideoElement>, "ref"> & {
audio?: boolean;
audioConstraints?: MediaStreamConstraints["audio"];
mirrored?: boolean;
screenshotFormat?: "image/webp" | "image/png" | "image/jpeg";
//between 0 & 1
screenshotQuality?: number;
videoConstraints?: MediaStreamConstraints["video"];
fullScreenRecord?: boolean;
screenshotDimensions?: ScreenshotDimensions;
setImageSrc?: Dispatch<SetStateAction<string>>;
overlay?: boolean;
}
export type Maybe<T> = NonNullable<T> | undefined;
export type VideoStatus = 'play' | 'error' | 'wait';
class CameraManager {
private setVideoStatus: Dispatch<SetStateAction<VideoStatus>>;
private videoRef: MutableRefObject<HTMLVideoElement | null>;
private audio: Maybe<boolean>;
private videoConstraints: CameraProps['videoConstraints'];
private audioConstraints: CameraProps['audioConstraints'];
private fullScreenRecord: Maybe<boolean>;
constructor({
audio,
setVideoStatus,
fullScreenRecord,
videoConstraints,
videoRef,
audioConstraints
}: Pick<CameraProps, 'audio' | 'fullScreenRecord' | 'videoConstraints' | 'audioConstraints'> & {
setVideoStatus: Dispatch<SetStateAction<VideoStatus>>,
videoRef: MutableRefObject<HTMLVideoElement | null>
}) {
this.setVideoStatus = setVideoStatus;
this.videoRef = videoRef;
this.fullScreenRecord = fullScreenRecord;
this.videoConstraints = videoConstraints;
this.audioConstraints = audioConstraints;
this.audio = audio;
this.requestUserMedia();
}
private async requestUserMedia() {
const portrait = window.matchMedia("(orientation: portrait)").matches;
try {
this.setVideoStatus('play');
const constraints: MediaStreamConstraints = {
video: this.fullScreenRecord ? {
aspectRatio: portrait ? document.documentElement.clientHeight / document.documentElement.clientWidth : document.documentElement.clientWidth / document.documentElement.clientHeight,
...(typeof this.videoConstraints === 'object' ? this.videoConstraints : undefined),
} :
typeof this.videoConstraints === 'object' ? {
...this.videoConstraints
} : true,
};
if (this.audio) {
constraints.audio = this.audioConstraints || true;
}
const stream = await navigator.mediaDevices.getUserMedia(constraints);
if (!this.videoRef.current) {
return;
}
this.videoRef.current.srcObject = stream;
return stream;
} catch (e) {
this.setVideoStatus('error');
if (e instanceof Error) {
// Handle specific errors here
}
console.log(e);
}
}
}
>Solution :
In your type declaration, you make videoContraints optional with the ?.
Pick constructs a new type from picking keys from another type, so you are essentially telling it to create this type with an optional property:
type SomeType = {
videoConstraints?: MediaStreamConstraints["video"];
}
When you assign a property to a different type which requires an optional property created by the Pick, it throws an error, whereas using the bracket notation is more lenient.
To use the Pick type, you can use ! to assert it’s defined:
this.videoConstraints = videoConstraints!;