#Function union type resulting in never argument
13 messages · Page 1 of 1 (latest)
Therefore typescript requires to you pass a value of type that matches all of those
"a" & "b" & "c" & "d"
type A = "a" & "b" & "c" & "d"
// ^? - type A = never
type Letter = "a" | "b" | "c" | "d";
type CommandBase<T extends Letter> = (letter: T) => void;
type ACommand = CommandBase<"a">;
type BCommand = CommandBase<"b">;
type CCommand = CommandBase<"c">;
type DCommand = CommandBase<"d">;
type Command = ACommand | BCommand | CCommand | DCommand;
interface CommandContainer {
execute: Command;
}
let execute = ((letter: "d") => {
console.log(letter);
}) satisfies Command
let container = {
execute: execute
} satisfies CommandContainer
const letter: "d" = "d";
execute(letter);
container.execute(letter);
This might help you
satisfies checks that a value matches a given type, but TS actually saves the value as the specific inferred type instead of widening it
const a: string = 'foo'
// ^? - const a: string
const b = 'bar' satisfies string
// ^? - const b: "bar"
if you've retrieved a command from a array of type CommandContainer[], you don't know which type of Command it is. What you're trying to do here is just not logically correct
if the commands are always DCommand, use DCommand[]
If they aren't always DCommand, you can't safely call it with "d"
You could save some extra information so that you can identify which it is
Preview:```ts
type Letter = "a" | "b" | "c" | "d"
type CommandBase<T extends Letter> = (
letter: T
) => void
type ACommand = CommandBase<"a">
type BCommand = CommandBase<"b">
type CCommand = CommandBase<"c">
type DCommand = CommandBase<"d">
type Command =
| ACommand
| BCommand
| CCommand
| DCommand
...```