简体   繁体   中英

Typescript infers object as never when checking if a conditional property exists

I have a type called T that accepts a generic type Str extends string . If the Str extends "hello" , then the type T should have an additional property called B . Something like this:

export type T<Str extends string> = {
  A: number;
} & (Str extends "hello" ? { B?: number } : {});

Based on that type, it behaves as follows:

type T1 = T<"hello">; // type T1 = { A: number; B?: number | undefined; }
type T2 = T<"world">; // type T2  = { A: number; }

Now, I want to create a function that accepts this type as an argument, and add an extra logic based on the existence of property B :

function t<Type extends string>(arg: T<Type>) {
  if ("B" in arg) {
    // ...
  }
}

Although, I get an error that arg inside the if statement is considered as never .

See playground

It works if you explicitly name the variant:

export type Test<Str extends string> = {
  A: number;
} & (Str extends "hello" ? { B?: number } : { });

type HelloVariant = Test<"hello">;

function t<T extends (HelloVariant | Test<string>)>(arg: T) {
  if ("B" in arg) {
    console.log(arg.B);
  }
}

Playground Link

Actually what needs to be named is the possibility of that string being a "hello". Here is more simplified version:

export type Test<Str extends string> = {
  A: number;
} & (Str extends "hello" ? { B?: number } : { });

function t<T extends (Test<"hello"> | Test<string>)>(arg: T) {
  if ("B" in arg) {
    console.log(arg.B);
  }
}

Link

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