typia icon indicating copy to clipboard operation
typia copied to clipboard

behavior of `undefined` with `exactOptionalPropertyTypes`

Open laura-a-n-n opened this issue 5 months ago • 6 comments

📝 Summary

When exactOptionalPropertyTypes is true in the TS configuration file, there appears to be an inconsistency in the generated runtime typechecking code vs. what tsc reports, in functions such as is<T>.

  • Typia Version: 9.6.0-dev.20250719
  • Expected behavior: Optional properties that are non-nullable should fail runtime typecheck when compared to undefined, when exactOptionalPropertyTypes is true.
  • Actual behavior: Typia allows explicit undefined for optional properties in any case.

Similar behavior can be seen in random<T>, which will generate explicit undefined values for properties that are only optional under this configuration.

Should Typia be supporting this case? I would appreciate your response, thank you :)

⏯ Playground Link

Unfortunately I cannot share a playground link, since the playground does not seem to have the exactOptionalPropertyTypes config enabled, and there is no way to edit the config from the UI.

💻 Code occuring the bug

import {is} from "typia";

// ensure `exactOptionalPropertyTypes` is on...

type T = {property?: string};

// this errors, because 'undefined' is not assignable to type 'string'
const x: T = {
  property: undefined,
};

// the following throws, because typia allows 'undefined' to be assigned to type 'string'
if (is<T>({property: undefined})) {
  throw new Error("'Undefined' is assignable to 'string'");
}

laura-a-n-n avatar Jul 31 '25 18:07 laura-a-n-n

Also the clone method adds properties with undefined as value if the properties is optional and not provided.

type TypeWithOptionalField = {
  requiredField: string
  optionalField?: string
}

// @ts-expect-error: Correctly gives ts error with exactOptionalPropertyTypes: true
const invalidTestObj: TypeWithOptionalField = {
  requiredField: 'test',
  optionalField: undefined
}

const result = clone<TypeWithOptionalField>({
  requiredField: 'test'
})

expect(result).toEqual({ requiredField: 'test' }) // fails, as result is equal to invalidTestObj

glumb avatar Aug 02 '25 10:08 glumb

I'm being careful for this issue because most use-case of typia's validator functions are:

  1. JSON parsed values
  2. AI function calling made parameters

If I distinguish the optional and undefindable types in the exactOptionalPropertyTypes, and some type that has not strictly distinguished them comes from as an external library, it can be a disaster for exactOptionalPropertyTypes configured users who are using typia for AI function calling development purpose.

samchon avatar Aug 10 '25 03:08 samchon

understood, thanks for looking into it :) could it be supported as a transform option?

laura-a-n-n avatar Aug 10 '25 04:08 laura-a-n-n

Okay, I'll support it by transform option.

samchon avatar Aug 10 '25 06:08 samchon

Understood your concerns. We are using typia to clone objects used in the Firebase database. Which allows optional fields, but no undefined values. Our workaround is to postprocess the cloned obj and remove all properties with undefined values. Which is kind of against the idea of typia where we don't have to iterate on objects during runtime.

It would be great to have some setting to toggle the behaviour.🙂

glumb avatar Aug 10 '25 06:08 glumb

Oh, sorry, I must have made a big mistake, confusing it with an old memory from the past. It seems like all the suggestions in this issue are feasible.

When exactOptionalPropertyTypes and undefined are configured at the same time, everything would be done in the next patch update.

samchon avatar Aug 10 '25 15:08 samchon