2

I'm trying to create a union type for arrow functions.

type ItemType = {
  createTime: number;
  totalTime: number;
  text: string;
};

type ObjType = {
  callback: ((item: string) => void) | ((item: ItemType) => void);
}

let obj: ObjType = {
  callback: (item: string) => {
    console.log(item)
  }
}

So far it works well.

And then I am going to call the function.

obj.callback('text');

It shows an error

Argument of type 'string' is not assignable to parameter of type 'string & ItemType'.
  Type 'string' is not assignable to type 'ItemType'.

The type of callback became (item: string & ItemType) => void.

Playground link

What am I doing wrong?

6
  • 1
    Thx for your comments. I found out it works on playground but it doesn't on my vscode. The type of callback becomes (item: string & ItemType) => void. I have no idea what is happening. Commented Feb 18, 2022 at 16:57
  • 1
    I wish it is just a typo or my mistake. imgur.com/a/owwb4l8 Commented Feb 18, 2022 at 17:14
  • 1
    This is why you have an intersection of both arguments catchts.com/react-props#first Commented Feb 18, 2022 at 18:15
  • 1
    @captain-yossarian - I had that suspicion -- but only after it didn't work. :-D Commented Feb 18, 2022 at 18:43
  • 1
    @T.J.Crowder usualy people are getting Argument of type XXX is not assignable to parameter of type 'never'. If you see this error in the question it is 90% that OP has union of functions Commented Feb 18, 2022 at 19:02

1 Answer 1

2

If ObjType has both possibilities, an object implementing it would have to implment both possibilities to be a valid ObjType. If obj is going to have only one version of the callback and not the other, I think you need to make ObjType generic and accept a type parameter saying which it will be, like this:

type ItemType = {
    createTime: number;
    totalTime: number;
};

type ObjType<Item extends string | ItemType> = {
    callback: (item: Item) => void;
};

let obj1: ObjType<ItemType> = {
    callback: (item) => {
        console.log(item);
    },
};
obj1.callback({createTime: 0, totalTime: 0});

let obj2: ObjType<string> = {
    callback: (item) => {
        console.log(item);
    },
};
obj2.callback("example");

Playground link

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.