最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TS2769: No overload matches this call - Stack Overflow

programmeradmin7浏览0评论

I have a function that accepts the types defined in A as an argument, but I want to make the typing more restrictive so I created B.

interface A {
    readonly x: any;
}

interface B extends Omit<A, 'x'> {
    readonly x: number;
}

The problem is, this function won't accept the types in B, even though it's more restrictive than A. Instead I get the error No overload matches this call, saying that Type(props: B) => number is not assignable to type (props: A) => number".

This function also won't accept props: { x : number }, giving me a similar error message.

I have a function that accepts the types defined in A as an argument, but I want to make the typing more restrictive so I created B.

interface A {
    readonly x: any;
}

interface B extends Omit<A, 'x'> {
    readonly x: number;
}

The problem is, this function won't accept the types in B, even though it's more restrictive than A. Instead I get the error No overload matches this call, saying that Type(props: B) => number is not assignable to type (props: A) => number".

This function also won't accept props: { x : number }, giving me a similar error message.

Share Improve this question edited Jul 12, 2021 at 10:01 JacksonCounty asked Jul 12, 2021 at 9:54 JacksonCountyJacksonCounty 1351 gold badge2 silver badges11 bronze badges 1
  • 1 Can you share a plete example? The code snippet does not give an error by itself. – Vojtěch Strnad Commented Jul 12, 2021 at 10:01
Add a ment  | 

2 Answers 2

Reset to default 3

The problem is that function arguments are contravariant. And their assignability is checked in the reverse direction pared to normal value types assignability. That's why you cannot assign a function accepting limited subset of values to the function accepting much wider set of values:

interface A {
    readonly x: unknown;
}

interface B extends Omit<A, 'x'> {
    readonly x: number;
}

declare function narrowerFn(props: B): number

const widerFn: (props: A) => number = narrowerFn // errror

playground link

It makes a perfect sense. Since the target side function can accept for example a string that source side function doesn't know how to deal with.

But it perfectly works in the opposite direction:

interface A {
    readonly x: string;
}

interface B extends Omit<A, 'x'> {
    readonly x: number | string;
}

declare function widerFn(props: B): number

const narrowerFn: (props: A) => number = widerFn

playground link

Since now the target side function can accept only a subset of values the source side function can deal with perfectly.

First of all, you do not need Omit. Just override the property as follows:

interface A {
    readonly x: any;
}

interface B extends A {
    readonly x: number;
}

Also, I've created the following example to highlight the problem:

TS Playground

type FA = (props: A) => number;

type FB = (props: B) => number;

const fb: FB = ({ x }) => x + 1;

const fa: FA = fb;

// Unsafe usage, cause fb expects numbers, not strings
console.log(fa({ x: '1' })); // Output "11" instead of 2
发布评论

评论列表(0)

  1. 暂无评论