On numerous occasions, I find myself facing the same dilemma. The data types are incorrect and additional verification is required.
Let's consider a simple example, where we have a Car class that allows us to retrieve a model name. Upon initialization of this class, the model property is set to null
.
We have two methods: one to set and another to get the model:
class Car {
private model: string | null
setModel() {
this.model = 'a3'
}
getModel() {
return this.model
}
}
While using this class, everything seems to work as expected, with the model being correctly defined in the order of execution.
But TypeScript only recognizes the original type as a string or null.
function searchForBrand(model: string) {
if (model === 'a3') return 'audi'
return ''
}
const car = new Car()
car.setModel()
console.log(car) // { model: 'a3' }
const currentModel = car.getModel()
console.log(currentModel) // a3
searchForBrand(currentModel) // Error: Argument of type 'string | null'
I am inclined to use !
(even though it's not ideal), or handle this issue within my function or beforehand.
This solution involves extra steps and might not be the most effective approach. What do you think?
The actual scenario where I face a similar challenge:
class Stream {
idealConstraint = {
width: { ideal: 1920 },
height: { ideal: 1080 },
frameRate: { ideal: 60 },
advanced: [ { zoom: 2 } ]
}
flux: MediaStream | null = null
async useStreamWithConstraints() {
const constraints = {
video: {
facingMode: FACING_MODE.ENVIRONMENT,
noiseSuppression: true,
},
audio: false
}
await this.useUserStream(constraints)
if (APP_MODE === 'development') await this.useDevelopmentStream()
await this.applyVideoConstraints(this.idealConstraint)
return this.flux
}
async useUserStream(constraints: MediaStreamConstraints) {
this.flux = await navigator.mediaDevices.getUserMedia(constraints)
}
async useDevelopmentStream() {
const developmentDeviceId = (await navigator.mediaDevices.enumerateDevices()).filter(device => device.label === 'OBS Virtual Camera')[0]?.deviceId
const developmentStream = await navigator.mediaDevices.getUserMedia({ video: { deviceId: developmentDeviceId } })
const developmentStreamDeviceId = developmentStream.getVideoTracks()[0]?.getCapabilities()?.deviceId
if (developmentStreamDeviceId === developmentDeviceId) this.flux = developmentStream
}
async applyVideoConstraints(constraints: MediaTrackConstraints) {
try {
const videoTrack = this.flux?.getVideoTracks()[0]
await videoTrack?.applyConstraints(constraints)
} catch (error) {
console.error('Could not apply constraints')
}
}
getFluxSettings() {
return this.flux?.getVideoTracks()[0]?.getSettings()
}
getFluxCapabilities() {
return this.flux?.getVideoTracks()[0]?.getCapabilities()
}
setZoom(zoomValue: number) {
return this.applyVideoConstraints({
advanced: [{ zoom: zoomValue }]
})
}
}