Repository: TypeScript
Issue: Concrete object not assignable to a generic mapped type with partially concrete constraint
Labels: Needs Investigation

# Bug Report

### 🔎 Search Terms

concrete object, assignable, generic mapped type, concrete constraint, partially

### 🕗 Version & Regression Information

- This is the behavior in every version I tried (interestingly though the intersected variant of this target type, presented in the playground, became valid in TS 3.6)

### ⏯ Playground Link

[Playground link with relevant code](https://www.typescriptlang.org/play?ts=4.8.0-dev.20220511#code/C4TwDgpgBAogHsATgQwMbBgNwgO2AHgCgooAVLXYKCBXAEwGcoBvKUSALigaQEscA5lAC+AGmJkKeUuGg1g9JuWx4A2gCJ2EdQF1CAPigBeSSqrzFLCVq7LKMyAG5CwiQH5TlCVxwRsiZ0ItMhQcBl5gXgB7HABhGIAzXgF8Uni8eVFPPGpaHEYWNlkuHkR+IWFDE2YJNEiYhjcuGpISG24+QWcSYWdewiDZKABJDMQGCHQIOlJQ8Pq4xOSAWWQwVPSFBCy7HIt8plZ20vKRKqsSVQBpKH5s4A0tXR0mkOQwiOjFnCSUtJitsAsvAkHUpARdkCoFd9Po+lAAGQXKDqABU6lsc0+MXSvw2AMy9zhLkCwVm73mX1xKzW+Iy23uuQUB0Kx06FXOLSg11uOHuj1kuigAB8UeiXlwbvsCmj1BISB5yR8FtS-ptCZD9PKoJiKdjvnj-vSoSCUOhwalwVkYcT+oQaGAoogqAkAK44dBfKACXAQMqoABiOEtZiZliOxQ6ZUEZwAFABKZGoBpUADuvAANnRUMhEDMsSqlkJqtrZc0oHUvgxy+11AwogBbCAAQU9MXUIhE4h6FaYybCwECJAA9MO2AALXhMBjjqKurNQABG0GQDHCAhwyEXGYgWTuwHH0AYyCbUFTyBAvYn0ASUQzGai6Zjq-XOCbOSnUAA8lcJDuqAoPC6sqVJFqs6zaqwybugoiA+K6DbLogXaQUUnD8pogo6CIEicsIV5aFECRnpm2a5vmeqFj8yRDlAo5QP2qCIBAChQGAiBRGAtxMC+ySbtu0DAFE14MTETEsdA7GcVARETp+DZrJAdBoRA1gQDwGjisYLD4auKmyemWY5nmSqUjiRaabotH0eEDaZrmvKwRMUzKcEaCoBAYDAEwB6foxzGsVEi4AFaTMAf4sWw6nAAATFwoxOWF0ymfqqrgUQrSFNBYzwYhfooZlEboZCAqQEKrgkHhBGyAZpHGRRIHmdRAh9EAA)

### 💻 Code

```ts
type ExtractEvent<
  TEvent extends { type: string },
  TEventType extends TEvent["type"]
> = TEvent extends {
  type: TEventType;
}
  ? TEvent
  : never;

type TransitionConfig<TContext, TEvent extends { type: string }> = {
  actions?: {
    type: string;
  };
};

type IntersectedTransitionConfigMap<TContext, TEvent extends { type: string }> = {
  [K in TEvent["type"]]?: TransitionConfig<TContext, ExtractEvent<TEvent, K>>;
} & {
  "*": TransitionConfig<TContext, TEvent>;
};

type TransitionConfigMap<TContext, TEvent extends { type: string }> = {
  [K in TEvent["type"] | "*"]?: K extends "*"
    ? TransitionConfig<TContext, TEvent>
    : TransitionConfig<TContext, ExtractEvent<TEvent, K>>;
};

export function genericFn<TEvent extends { type: string }>() {
  const wildcardTransitionConfig = {
    "*": { actions: { type: "someAction" } },
  } as const;

  // this should be assignable, in the same way as the following assignment is OK
  let test: TransitionConfigMap<
    { counter: number },
    { type: TEvent["type"] }
  > = {} as typeof wildcardTransitionConfig;

  // concrete prop is assignable to the concrete prop of this mapped type
  test["*"] = {} as typeof wildcardTransitionConfig["*"];

  // similar intersected type accepts this concrete object
  let test2: IntersectedTransitionConfigMap<
    { counter: number },
    { type: TEvent["type"] }
  > = {} as typeof wildcardTransitionConfig;
}
```

### 🙁 Actual behavior

The concrete object is not assignable to this generic mapped with a partially concrete constraint

### 🙂 Expected behavior

This should be allowed, or the second assignment (the one to `test['*']`) should also be considered as invalid.

--- 

The problem originates [here](https://github.dev/microsoft/TypeScript/blob/9236e39374c0ec9a1e3f9894af4fb9eb34ba0021/src/compiler/checker.ts#L19523) where this relation check fails:
```ts
indexedAccessType // { readonly "*": { readonly actions: { readonly type: "someAction"; }; }; }[(("*" | TEvent["type"]) & "*") & K]
templateType // (K extends "*" ? TransitionConfig<{ counter: number; }, { type: TEvent["type"]; }> : TransitionConfig<{ counter: number; }, ExtractEvent<{ type: TEvent["type"]; }, K>>) | undefined
isRelatedTo(indexedAccessType, templateType, RecursionFlags.Both, reportErrors) // 0
```
Which leads us to checking if a type is assignable to a conditional type and that is rarely even possible, as only limited scenarios are even checked for such a case ([here](https://github.dev/microsoft/TypeScript/blob/9236e39374c0ec9a1e3f9894af4fb9eb34ba0021/src/compiler/checker.ts#L19541-L19544))