#Change type of generic function depending on a boolean argument

15 messages · Page 1 of 1 (latest)

tall kettle
#

Hi! I have the following code:
https://www.typescriptlang.org/play?ts=5.2.2#code/JYOwLgpgTgZghgYwgAgGIHsoFtkG8BQyRyIEAzpACYBcehxRMwEANjSQK5YBG09RAX3xD8CdCArIOZCBmzIAvMgA8ASTIBRSsDDIIAD0ghKZZN3ToWEOCAB8AChiYstdVp17DEY6bBQOKAD8aM7ItAAKcFBgwHAsynJYtgA0yMCa2mCuGToAlIq2dAzAMMj26e5g+QQMDE7YAHSkFBCUDUyslPzIQgJAA

currently the following code gets me a warning inside the condition because the compiler cannot resolve that the form type inside the condition should be a Form and not a Partial<Form>, is there any way to make this work?

pure jettyBOT
#

@tall kettle Here's a shortened URL of your playground link! You can remove the full link from your message.

freezee#0

Preview:```ts
interface Form {
nested: {
field: number
}
}

const useForm = <IsEdit extends boolean>(
form: IsEdit extends true ? Form : Partial<Form>,
isEdit: IsEdit
) => {
if (isEdit) {
form.nested.field
}
}```

lament heron
#

conditionals in signatures almost never work properly.

#

generally you'd use overloads for this.

#

IsEdit could be boolean here, causing a disconnect

#

the 2 values aren't linked anyways though, actually

tall kettle
#

sadly there's way too much behavior inside this function to create two overloads
could there be an alternative? I just need a way to have either the Form or the partial variant depending on a condition with the same code

lament heron
#

couldn't you just have 2 separate functions based on the isEdit value?

#

well, that just kinda moves the problem back a step

#

you could make a discriminated union with a single function as well

tall kettle
#

could we make this work with a type guard function? idk like isNotPartial = (form: Partial<Form>): form is Form => { check for every field presence }

pure jettyBOT
#
that_guy977#0

Preview:```ts
...
type FormData_ =
| {
form: Form
isEdit: true
}
| {
form: Partial<Form>
isEdit: false
}

const useForm = ({form, isEdit}: FormData_) => {
if (isEdit) {
form
//^?
} else {
form
//^?
}
}
...```

lament heron
#

although, a full Form would still be a valid Partial<Form>, and logically, all new (at least, top-level) data would also be a valid edit, wouldn't it?

tall kettle