#variable of type "never" using inferred type from an object.

10 messages · Page 1 of 1 (latest)

coarse crownBOT
#

@cyan pulsar Here's a shortened URL of your playground link! You can remove the full link from your message.

arfka#0

Preview:ts const data = { A: { selector: "AA_selector", childrens: { A1: { selector: "AA1_selector", childrens: { A11: { selector: "AA11_selector", childrens: {}, }, A12: { selector: "AA12_selector" ...

cyan pulsar
#

variable of type "never" using inferred type from an object.

midnight ice
#

keyof typeof parent['childrens'] is already never

#

keyof only takes keys known to all branches

#

if you want to get all possible keys you'll need to distribute

#

but that doesn't really solve it, since ts doesn't know what child you actually have. this is a correspondance problem i think

#

!:corr*

coarse crownBOT
#
retsam19#0
`!retsam19:correspondence-problem`:

There's a particular pattern that is safe but hard for the Typescript compiler to handle, which I call the "correspondence problem":

const functionsWithArguments = [
  { func: (arg: string) => {}, arg: "foo" },
  { func: (arg: number) => {}, arg: 0 },
];

for (const { func, arg } of functionsWithArguments) {
  func(arg);
//     ^^^
// Argument of type 'string | number' is not assignable to parameter of type 'never'.
//   Type 'string' is not assignable to type 'never'.
}

The problem is that func is typed as (x: string) => void | (x: number) => void and arg is string | number, but the compiler can't prove that they "correspond": that, for example, arg is only a string when func accepts strings.

As far as the type are concerned, arg could be number, and func could be (arg: string) => void, and that would be a type-error. It's easy for us to see that that won't happen, but that requires understanding the program at a higher-level than the level the compiler operates.

Depending on the specifics there's sometimes clever fixes, but usually I recommend using a type assertion and ignoring the issue:

func(arg as never);
cyan pulsar
#

thank you first of all.
so accodring to you, it's practically impossible to infer this type.
the best i can do is create a generic type :
like

type childrenGeneric = {
  selector: string;
  childrens: Record<
    string,
    {
      selector: string;
      childrens: Record<string, Record<string, string>>;
    }
  >;
};
//....
const subTypeObject =parent.childrens[children] as childrenGeneric;