简体   繁体   中英

TypeScript: Typing problem with “A extends B”

[Edit - concluding remark]: It has turned out that the question below was mainly the result of some suboptimal typings and normally you might not have such issues like I had in my program => now with this knowledge, my question does not seem to make too much sense any more (as others have already mentioned below).


Please have a look at the following TypeScript code snippet. As B extends A this c: 8 line is of course allowed. How do I have to change the types of function f to forbid others keys next to a and b ?

type A = { a: number, b: number }

function f<B extends A>(b: B): void {
}

f({
  a: 3,
  b: 4,
  c: 8 // <- This shall cause a compile error
})

» Demo

PS: Of course function f(b: A) {} is not what I am looking for. This example here is just simplified, the real world use-case is far more complicated... it's important that function f stays generic.


[Edit]: As my simplification above caused some confusion: Please find here a more complex example, where an anwer to my question above could help (an imaginary UI component API):

Please have a look at the type error in Demo-A. This shall be fixed in Demo-B.

Demo-A (with type error)

Demo-B (without type error)

But as you can see in Demo-B you can now add invalid parameters to the component configuration - which is not very nice... and that's why I have asked the question above.

[Edit - later] Not an answer to my question above, but at least the following modification of Demo-B should work as desired: Demo-C

The behavior is by design. TS is structural type language where type compatibility is based on subtypying, in other words every type which has all constraints will pass the rule. In your example type of the value has all fields needed, so 'a' and 'b', therefore everything is ok.

There is no reason you should not allow for such object to be passed, as additional fields inside should not make you a difference. Saying that you extend means saying you are allowed to have more fields in terms of composites like objects.

Additional if you want a subtype, but with exact fields the only type which matches your need will be unfortunately A , so the function signature should be f(a: A) .

And to be clear even with f(a: A) you will be able to pass values with additional fields, only object literals will be validated strictly. Any assigned value with more fields can be used without compiler complain. And the reason I describe already.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM