#`null` not assignable to `something | null` (????)

83 messages · Page 1 of 1 (latest)

north cloak
#

I'd also appreciate any help making that inner conditional more elegant cause I feel like there must be an easier way to allow nulls than this

analog juniper
#

conditional return types never seem to go well

#

overloads might work for that

north cloak
#

they didn't

#

I ended up using as any heh

analog juniper
#

😬

burnt creek
chrome merlinBOT
burnt creek
#

!ts

chrome merlinBOT
#
function convert<T extends Record<string, any> | null | undefined>(
	object: T,
): T extends Record<string, any>
	? {
			[key in keyof T]: T[key] extends Date
				? Timestamp.AsObject
				: T[key] extends Date | null
				? Timestamp.AsObject | null
				: T[key];
	  }
	: T;
function convert<T extends Record<string, any> | null | undefined>(
	object: T,
) {
	if (typeof object === 'undefined' || object === null) {
		return object;
	}

    const cloned = {...object};

    // ...

	return cloned;
}

namespace Timestamp {
    export class AsObject {}
}```
burnt creek
#

magic!

north cloak
#

wow huh

#

okay then

burnt creek
north cloak
#

cloned has wrong type

#

what on earth is T & ({} | undefined)

analog juniper
north cloak
#

that's not exclusion tho

#

or not even sure what that is tbh

#

what is & undefined even

analog juniper
analog juniper
north cloak
#

ok also is it possible to like

#

"get" the output type based on an input

#

like all inside the type system

#

like I mean

#
let something: convert(someOtherType)
#

or something like that

#

huh

#

Like I mean I could use ReturnType<convert> but that wouldn't adjust for the input generic

#

wait I got it

analog juniper
#

ReturnType<typeof convert<typeof someOtherType>>?

north cloak
#

yeah

#

alright thanks

#

oh one last thing

#

is it really not possible to simplify this

#

now that I have to also handle undefined it's going to span a bunch of lines just to handle undefined/null values

burnt creek
analog juniper
burnt creek
#

i forgot instantiation expressions were a thing

north cloak
analog juniper
#

why do you even have something that could be | null | undefined

burnt creek
#

use a union

analog juniper
#

that seems like code smell

north cloak
#

protobuf reasons

north cloak
analog juniper
#

T[K] extends Timestamp.AsObject | null | undefined ? Date | <nullish in T[K]> : T[K]

burnt creek
#

Date extends T[Key] ? Exclude<T[Key], Date> | Timestamp.AsObject : T[Key]

#

woops

analog juniper
#

where nullish in T[K] could be

  • Exclude<T[K], Timestamp.AsObject>
  • Extract<T[K], null | undefined>
  • T[K] & (null | undefined)
burnt creek
north cloak
#

what

#

let me try copy paste this

burnt creek
analog juniper
#

would need to be Timestamp.AsObject extends T[K]

burnt creek
#

oh

#

yeah woops

analog juniper
#

but also wouldn't that also handle unions with other values? that wouldn't match the original behavior (although idk what the intended behavior is so eh)

burnt creek
#

wrong order tho

north cloak
#

I'm making two functions to go back and forth between the types so yeah

analog juniper
#

the Date and Timestamp.AsObject are reversed but otherwise it's the same idea as what i have

burnt creek
#

ah

analog juniper
#

(or maybe just handle all unions like in n_n's)

north cloak
#

I did like n_n's

analog juniper
#

hmm no, generic still seems hella helpful

north cloak
#

I mean they're separate functions

#

not one function to go back and forth

analog juniper
#

type Transform<U, From, To = never> = From extends U ? Exclude<U, From> | To : U;
type T = Transform<string | number, number, boolean>;

analog juniper
north cloak
#

this is beyond my IQ

#

I'm so sorry

analog juniper
#

since you were confused about the intersection being an "exclude"/"extract" earlier, i think you may just be misunderstanding intersections/unions/Exclude/Extract as a whole

north cloak
#

of course

analog juniper
#

that reply is so relatable tbh

north cloak
#

I learned these a couple times

#

still need to learn them couple times more

analog juniper
#

if you're familiar with set theory, that'll help a lot

#

types are sets, values are elements of those sets