Skip to content

Intersection with mapped type broken in function with generic in 4.1.2 #41655

Closed
@avaly

Description

@avaly

TypeScript Version: 4.1.2 and 4.2.0-dev.20201123

Search Terms: UpdateQuery, Intersection, Generic

Code

import { UpdateQuery } from 'mongodb';

interface Foo {
  foo: string;
}

function testWithGeneric<TSchema>(): UpdateQuery<TSchema> {
  const update: UpdateQuery<TSchema> = {};

  if (Math.random() < 0.5) {
    const key: string = 'newKey';
    const value: any = true;

    update.$set = {
      ...(update.$set || {}),
      [key]: value
    };
  }

  return update;
}

function testWithoutGeneric(): UpdateQuery<Foo> {
  const update: UpdateQuery<Foo> = {};

  if (Math.random() < 0.5) {
    const key: string = 'newKey';
    const value: any = true;

    update.$set = {
      ...(update.$set || {}),
      [key]: value
    };
  }

  return update;
}

Where the UpdateQuery definition in the mongodb types is defined as:

type DotAndArrayNotation<AssignableType> = {
    readonly [key: string]: AssignableType;
};

type ReadonlyPartial<TSchema> = {
    readonly [key in keyof TSchema]?: TSchema[key];
};

export type MatchKeysAndValues<TSchema> = ReadonlyPartial<TSchema> & DotAndArrayNotation<any>;

export type UpdateQuery<TSchema> = {
    $set?: MatchKeysAndValues<TSchema>;
    // other fields here don't matter
};

Expected behavior:

Code is valid.

Actual behavior:

Only the function testWithGeneric throws an error. But since MatchKeysAndValues is defined as an intersection between ReadonlyPartial<TSchema> and a mapped type of string keys with any values, it should be accepted.

Type '{ [x: string]: any; }' is not assignable to type 'MatchKeysAndValues<TSchema>'. Type '{ [x: string]: any; }' is not assignable to type 'ReadonlyPartial<TSchema>'.

This used to work in version 4.0.5.

Playground Link: https://www.typescriptlang.org/play?ts=4.1.2#code/JYWwDg9gTgLgBAbzgVTAEwIYwKYEUCu2UAnnAL5wBmUEIcA5CBAHYDmEaARvQNwCwAKEHBmOKJQwBjbHABiECIkFwqCgFxwAzjCgjW-AWUGDK+ZpJjAWcHNoDqwGAAsA4tmZFgkgDwAVAMqSTtggGAB8ABQAlBqomDgERMR+gcGhYUoCKpIs2nD46FjYsYUJhCQpQSHhcAC8iGQGynDAlHARALJYTgB0UBjMaLTRcN5wAAw9AKxRmSrZufAA1tjEGtq6bHUMHgDuANKrvM0LzHkAbhgANoQaA6T1OoRNWfMF8dg9ACSa2PD1CBO8x6IIi7yK31+8AAPtCGlEADRAlQAbRWxAAuhpLjdsEDGs0jEJXlA-vgoMx8qVsAYiSYzBYrJTbDAHM4IPgYG4PLpJNESh9EhV5BAMoDXjkzvBwTgBUUhckRRkAQTiSpWu0us4+gMhiARmNJjM5vNJXl0esdHptvQ9odiMdXqcLtdbnB7tsnjTjE6qR9IX9tuL5sDQTLPj9A7D4Ujfaj0Vi4DjCPiDCo6SSyRS-UVaYIgA

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions