我有一个如下所示的界面
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;
}
当我使用 pick 来选择这样的属性之一时
private videoConstraints: Pick<CameraProps, 'videoConstraints'>;
我在这行代码中遇到了这个错误
this.videoConstraints = videoConstraints;
输入布尔值 | MediaTrack 约束 |未定义不可分配给类型 Pick
类型“未定义”不可分配给类型“Pick”
似乎选择从我的类型中删除未定义的内容,但是当我编写如下代码时
private videoConstraints: CameraProps['videoConstraints'];
一切都很好
完整代码如下
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);
}
}
}
那是因为
Pick
并没有像你想象的那样做。它返回一个复合类型,其中包含从其他类型中选择的属性。它不返回单个选定属性的类型。
请参阅此示例(游乐场):
type Stuff {
a?: string
b?: number
}
// The type is { a?: string | undefined }
type T1 = Pick<Stuff, 'a'>
// The type is string | undefined
type T2 = Stuff['a']
所以
选择
;
评估输入
{ videoConstraints?: MediaStreamConstraints["video"] }
但你已经发现了
CameraProps['videoConstraints']
是你真正需要的。这将评估为
MediaStreamConstraints["video"] | undefined