I want to understand why type S1 is never, but when I remove the label or customRef properties I get correct result of string. When I remove the value and label properties I get unknown.
export interface BaseInputProps<TStored> {
value: TStored;
customRef?: (selfProps: this) => void;
}
export interface TestInput extends BaseInputProps<string> {
label: string;
}
type InferStoredType<T> = T extends BaseInputProps<infer TT> ? TT : never;
type S1 = InferStoredType<TestInput>;
What is happening here?
Typescript version 3.7.5. Works the same way on the Typescript playground.
It has to do with the structural difference and weak type. So let's understand your problem in all the cases
Case 1: By default, it is never
When you try to extend
interface TestInputwithinterface BaseInputProps<string>it will try to check if all the properties typing are compatible but in this casecustomRef?: (selfProps: this) => void;type(selfProps: this)=> voidis not assignable tostringand vice versa. That's why it is falsy inheritance because of which S1 isnever
Case 2: When you remove label and customRef, it is string
When you removed label and customRef
interface BaseInputPropsandinterface TestInputwill be left out with one compulsory propertyvaluebecause of which it will correctly infer the typings.
Case 3: When you remove value and label, it is unkown
When you removed the value and label
interface BaseInputPropsandinterface TestInputwill be left out with only optional property and typescript can't guarantee the typings in this case.
Still, why this change was intentional is a question. But, looking at the scope of the spec change it will involve, I guess it's very difficult to see a change in this.
Please read this too for more on weak typing and on conditional typings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With