#This expression is not callable.

34 messages · Page 1 of 1 (latest)

ocean stump
#
// utility type for declaration.
// Go through a generic object and replace all instances of a type with another type.

type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType?
  ? ToType // Yes, replace it
  : Type extends object // If the key in the object is another object, call the function again; else use the basic type it has declared. ToType would've replaced it already if it was our source type
  ? ReplaceTypes<Type, FromType, ToType> // Yes
  : Type; // No, leave it alone

export type ReplaceTypes<ObjType extends object, FromType, ToType> = {
  [KeyType in keyof ObjType]: ReplaceType<ObjType[KeyType], FromType, ToType>; // Call above function for every key in the object
};

/* example
type k = {
  a: number;
  b: string;
};

type l = ReplaceTypes<k, string, boolean>;
const _x: l = {
  a: 1,
  b: true
};

*/

const fkt = () => {
  return 'awd';
};

type l = ReplaceTypes<typeof fkt, string, boolean>;

const _x: l = () => {
  return '';
};

let _o = _x();

Above script works great for objects, but has problems with functions as _x() complains of a missing call signature which shouldn't have been replaced in the first place. How can i match for "callable" and then not modify the type so the compiler knows whats up or modify the type so the call signature is added?

zinc shoal
#

This works for functions taking no arguments. Should be possible to allow it to take arguments as well, presumably you want the types in the argument to be replaced?

cloud forgeBOT
#
cg5#4835

Preview:```ts
// utility type for declaration.
// Go through a generic object and replace all instances of a type with another type.

type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType?
? ToType // Yes, replace it
: Type extends () => infer T
...```

ocean stump
#

the functions should just stay untouched

#

Guessing if i change it to

type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType?
  ? ToType // Yes, replace it
  : Type extends () => infer T
  ? () => FromType
  : Type extends object // If the key in the object is another object, call the function again; else use the basic type it has declared. ToType would've replaced it already if it was our source type
  ? ReplaceTypes<Type, FromType, ToType> // Yes
  : Type; // No, leave it alone

it works as i want it ?

zinc shoal
#

If you want to allow arguments in the function, but leave them unchanged:

cloud forgeBOT
#

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

cg5#4835

Preview:```ts
// utility type for declaration.
// Go through a generic object and replace all instances of a type with another type.

type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType?
? ToType // Yes, replace it
: Type extends (...args: infer Tuple) => infer T
...```

zinc shoal
#

Oh right, you want to leave all function types unchanged entirely. Not the arguments or the return type

ocean stump
#

yeah i want to change nothing abt functions

zinc shoal
#

Then I guess you can just

  ? Type```
ocean stump
#

End Goal:
I want to use Material UI palette module augmentation to add SimplePalettes to custom colors, but when in code it should only be one that is currently enabled

cloud forgeBOT
#
ZweiEuro#2274

Preview:```ts
// utility type for declaration.
// Go through a generic object and replace all instances of a type with another type.

type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType?
? ToType // Yes, replace it
: Type extends Function
? Type
...```

ocean stump
#

like so ?

zinc shoal
#

Yeah. But export ReplaceType and not ReplaceTypes. ReplaceType will work for primitives, objects and functions all the same. I would rename ReplaceTypes to ReplaceTypesInObject

#

Oh - there is a case, where there is a type like {x: string, (): void} where you want to replace the type on x but leave the call signature unchanged. I'll need to think about that or maybe someone else knows

ocean stump
#

yeah honestly The cases i got covered with this are more than enough for now. its supposed to be a quite simple interface if someone wants to attach something that odd its on them

#

... wait wouldn't in that case just trigger the recursion on that object and treat them independently ?

zinc shoal
#

In that case, {x: string, (): void} extends Function so it would do nothing

ocean stump
#

like

type k = {
x: string,
(): void
}

type l = ReplaceTypeInObject(k, string,number);


#

would leave x as a string ?

zinc shoal
#

Calling ReplaceTypeInObject on that would make the call signature disappear like you had before. But you can use ReplaceType always

ocean stump
#

Ok I'll give a more concrete example as this is a bit confusing to me now

cloud forgeBOT
#
ZweiEuro#2274

Preview:```ts
interface SimplePaletteColorOptions {}

interface zOptionSettings {
visualizer: {
// general styling inside the visualizer
// regarding sidebar and components inside the sidebar
sidebar: {
batt
...```

ocean stump
#

this is what i want to do,
sorry if its a lot but it boils down to, i want the palette objects to become strings but leave all other things untouched

zinc shoal
#

Okay, there are no weird functions with extra fields, or anything. And the thing you are converting is an object. So the one from earlier should work just fine, regardless of whether you use ReplaceType or ReplaceTypeInObject. Just -- if SimplePaletteColorOptions is the empty interface, because of structural typing, the entire zOptionSettings will be a SimplePaletteColorOptions and will get replaced. In practice the real interface will have some fields, but otherwise for testing you can just add some random fields

cloud forgeBOT
#

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

cg5#4835

Preview:ts type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType? ? ToType // Yes, replace it : Type extends Function ? Type : Type extends object // If the key in the object is another object, call the function again; else use the basic type it has declared. ToType would've replaced it already if it was our source type ...

zinc shoal
#

(I had to remove some fields to get past max discord message length, but the principle is the same)

ocean stump
#

the real interface just has 3 colors, main,light, dark , contrast or smth

zinc shoal
#

yeah, just needs to be enough to not accidentally match some other part of the structure, which it will

#

I convinced it not to be lazy

cloud forgeBOT
#
cg5#4835

Preview:ts type ReplaceType<Type, FromType, ToType> = Type extends FromType // FromType? ? ToType // Yes, replace it : Type extends Function ? Type : Type extends object // If the key in the object is another object, call the function again; else use the basic type it has declared. ToType would've replaced it already if it was our source type ? ...

ocean stump
#

thanks for your help !

#

!solved