#Why don't I get an error on this potential strictNullChecks violation?

38 messages · Page 1 of 1 (latest)

verbal notchBOT
#
sleepeasysoftware#0

Preview:```ts
interface Foo<T> {
notUndefinedOrNull?: string[]
bar: T
}

function assignBadValues<T>(foo: Foo<T>) {
foo.notUndefinedOrNull = foo.notUndefinedOrNull?.map(
s => {
// ^ I would have expected an error since it could = undefined
...```

clear flame
#

!ts

verbal notchBOT
#
interface Foo<T> {
  notUndefinedOrNull?: string[];
  bar: T;
}

function assignBadValues<T>(foo: Foo<T>) {
  foo.notUndefinedOrNull = foo.notUndefinedOrNull?.map((s) => {
    return s;
  });
}
jagged falcon
#

You have exactOptionalPropertyChecks turned off

verbal notchBOT
#

interface Foo<T> {
  notUndefinedOrNull?: string[];
  bar: T;
}

function assignBadValues<T>(foo: Foo<T>) {
  foo.notUndefinedOrNull = foo.notUndefinedOrNull?.map((s) => {
//^^^^^^^^^^^^^^^^^^^^^^
// Type 'string[] | undefined' is not assignable to type 'string[]' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.
//   Type 'undefined' is not assignable to type 'string[]'.
    return s;
  });
}
clear flame
#

that must be a relatively new one. I didn't know it existed (and neither did chatgpt)

#

I think you meant exactOptionalPropertyTypes btw

jagged falcon
#

Oops, yeah

#

The TS snippet I thought was going to show that I'd turned it on... apparently not, I want to change that behavior in the bot.

versed hollow
#

Not particularly new, but also one of the more niche rules. It's not part of strict: true and there's valid mistakes that it can catch but they're fairly uncommon.

clear flame
versed hollow
#

Depends on who you ask - it is actually marked as "recommended" on the docs, but personally it's not one I generally turn on if I don't have a specific reason to

#

I find the behavior a little more annoying and it's neer seemed valuable enough to me to go through and turn it on in existing projects, but there's probably not much downside to turning it on in new ones

clear flame
#

I wish I could turn it on for a type instead of a project

#

or at least something finer grained than a project

versed hollow
#

Would be a bit weird to be inconsistent there.

clear flame
#

Yeah but my case seems like it may be relatively common: a exactOptionalPropertyTypes is important for a library's types

#

And if you make libs and don't use this, you're making it more inconvenient for everyone else to use it

hallow vault
#

eOPT specifically fixes the problem that "I want { key: undefined } to be treated differently from {}" which is a mostly niche problem.

versed hollow
#

I was curious how many errors I'd have to fix on my main project:

Found 119 errors in 72 files.

clear flame
versed hollow
#

I'm sure a lot of those would be trivial... but funnily enough the very first one I look at is an issue in the typings of a library that I'm using.

verbal notchBOT
#
retsam19#0

Preview:```ts
import {ExpirationPlugin} from "workbox-expiration"
import {StaleWhileRevalidate} from "workbox-strategies"

new StaleWhileRevalidate({
plugins: [new ExpirationPlugin()],
})```

versed hollow
#

But yeah, it's probably something libraries should turn on, since if they don't they may make issues like this.

clear flame
#

thanks

#

!resolve

jagged falcon
# clear flame What I mean is, if you're a lib author you're probably typing your stuff incorre...

I think this is actually backwards. If a lib turns that flag on, it means they are expecting { option: undefined } to be invalid. If they don't, then they'll most likely handle {} and { key: undefined } the same way... in order words, a library which turns that option on effectively forces consumers to also turn it on, unless they specify all optional values as { key?: string | undefined } in their public API.

hallow vault
#

Yeah eOPT is infectious, if you turn it on then you force every down stream consumer to have to turn it on.

#

And the { key: undefined } vs {} problem isn't exactly common, unless you have code that deals with key in obj/Object.keys(obj)/Object.hasOwnProperty(obj)/etc.

jagged falcon
#

I agree it'd be neat to be able to specify it as a modifier on a property/index signature...

#

{ exact a?: string; b?: string }, { a: undefined } would be invalid

#

Then declarations for libraries which have the annoying version of the behavior could use that to indicate that they're finicky

old granite
#

I'm excited for exact { exact a?: exact string; b?: string } to come to the language

#

I really have seen exact recommended in all 3 of those positions lol

clear flame
#

let me start over

#

If a lib turns that flag on, it means they are expecting { option: undefined } to be invalid.
I don't think that can be assumed. They can explicitly state in their types that it's valid or invalid. Without that flag, it's ambiguous.

Am I misunderstanding how it works?

hallow vault
# clear flame > If a lib turns that flag on, it means they are expecting { option: undefined ...

If you are the library, and you have eOPT turned on, the following code:

function fn(obj: { key?: string}) {
    if ('key' in obj) {
        obj.key.length
    }
}

The in your own code you are not allowed to call fn({ key: undefined }) and everything is fine.
However, a consumer of your library might not have eOPT turned on, and if they don't then calling fn({ key: undefined }) is allowed, which explodes your library code.