Summary
I want to ask how you think about introducing omit-key syntax when the value is undefined. I think this syntax is convenient when we need to omit key of undefined value specifying arguments.There some libraries tell apart whether key exists or not even if its value is undefined. Prisma is one of them. This throws an error when specifying undefined value with key. So, I want to write codes like followed by an example.
Specification
New syntax is ?
after object key.
It's also allowed to dynamic property key
var example = {
a?: input.a // omitted if input.a === undefined
[b.name]?: input.b.value // omitted if input.b.value === undefined
c: input.c
}
If input.a = undefined
, input.b.name = 'foo'
and input.c = undefined
, the output of example value is
{
c: undefined
}
Usage
prisma.model.findMany({
where: {
required_value: query.required_value,
city_name?: query.city_name
}
})
and interpret if query.city_name is undefined.
prisma.model.findMany({
where: {
required_value: query.required_value,
}
})
This is possible if we can transpile the first code to
function omitUndefined(value, omitKeysIfUndefined) {
return omitKeysIfUndefined.reduce(function(r, key) {
if(value[key] === undefined) {
delete r[key]
}
return r
}, value)
}
prisma.model.findMany({
where: omitKeysIfUndefined({
required_value: query.required_value,
city_name: query.city_name
}, ['city_name'])
})
Problem
Current if we write codes
let additionalParams = {}
if(pattern_1 !== undefined) {
additionalParams = {
...additionalParams,
pattern_1: pattern_1
}
}
if(pattern_2 !== undefined) {
additionalParams = {
...additionalParams,
pattern_2: pattern_2
}
}
prisma.model.findMany({
where: {
required_value: query.required_value,
...additionalParams
}
})
and in this way, type inference is hard in typescript, and if code logic is long code becomes unreadable.
We may be able to automatically omit undefined properties in the way removing all simply by function.
const isObject = (value) => !Array.isArray(value) && typeof value === 'object' && value !== null
export function omitUndefined(
value
) {
if (Array.isArray(value)) {
for (const val of value) {
if (typeof val === 'object') {
omitUndefined(val)
}
}
}
if (isObject(value)) {
const iterator = Object.keys(value)
for (const it of iterator) {
const child = value[it]
if (isObject(child)) {
omitUndefined(child)
}
if (child === undefined) {
delete value[it]
}
}
}
return value
}
But it's not ideal in the point of typing and it's rare but there are cases we want to remain undefined for setting defaultValue or loop logic, so configurable syntax looks ideal.