TypeScript: TS2322 error when using satisfies with strictFunctionTypes
🔎 Search Terms
satisfies strictFunctionTypes 2322
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about strictFunctionTypes
⏯ Playground Link
💻 Code
type FuncProps = {
foo: string;
}
const bar = ({ foo }: FuncProps) => `foo: ${foo}`;
function baz({ foo }: FuncProps) { return `foo: ${foo}`; }
const fns = {
test1: bar,
test2: baz,
} satisfies Record<string, ((props: Record<string, unknown>) => string)>;
🙁 Actual behavior
Type ‘({ foo }: FuncProps) => string’ is not assignable to type ‘(props: Record<string, unknown>) => string’. Types of parameters ‘__0’ and ‘props’ are incompatible. Property ‘foo’ is missing in type ‘Record<string, unknown>’ but required in type ‘FuncProps’.
🙂 Expected behavior
No error, I’m just using satisfies and type of __0 satisfies the one from props
Additional information about the issue
Using ((props: any) => string)
“fixes” the error but is something I try to avoid
About this issue
- Original URL
- State: closed
- Created 10 months ago
- Comments: 15 (4 by maintainers)
Yeah, you can’t do that with an assignability check (which is all that
satisfies
is), because assignability goes in the opposite direction for function parameters, hence contravariance. AFAICT the check you want to do isn’t possible in the current type system.So what you’re asking for, if I’m reading this right, is a way to say (using the animal analogy again):
Animal
, but the exact type of the parameter doesn’t matter.”IMO it doesn’t really make sense to specify a type this way, since it doesn’t give you enough information to do anything with it. You couldn’t safely pass a random
Animal
to it, since it might require something specific (say, aDog
), but you also don’t know exactly what kind of animal it wants. Accordingly, there’s no way to specify this type (well…strictFunctionTypes: false
allows it, but it’s unsound).Think of it this way:
Dog
is assignable toAnimal
because a dog is an animal, right? Anything you can do with any animal, you can do with a dog. But(x: Dog) => void
is not assignable to(x: Animal) => void
because someone might call the function with a cat, but your implementation can only deal with dogs.This is called contravariance and is what
strictFunctionTypes
enforces.