Skip to content

Two types should only be compatible if their members are compatible - even if all these members are optional #12904

Closed
@DmitryEfimenko

Description

@DmitryEfimenko

I wanted to see if I can update definitions a MongoDB filter object, which utilizes these expressions. Below is just a start, but I already see an issue when the code compiles when it should not. This issue possibly has similar underlying issue as #12769

TypeScript Version: 2.1.4

Code

type MongoFilter<T> = $and<T> | $or<T> | propertyRule<T>;

type logical<T> = $and<T> | $or<T>;

type $and<T> = { $and: Array<logical<T> | propertyRule<T>> }
type $or<T> = { $or: Array<logical<T> | propertyRule<T>> }

type propertyRule<T> = {
  [P in keyof T]?: T[P] | comparison<T[P]>
}

type comparison<V> = $eq<V> | $gt | $lt;

type $eq<V> = { $eq: V };
type $gt = { $gt: number };
type $lt = { $lt: number };

// See if MongoFilter works:
interface Person {
  id: number;
  name: string;
  age: number;
}

// should compile
let f1: MongoFilter<Person> = { $or: [{ id: 1 }, { name: 'dima' }] };
let f2: MongoFilter<Person> = { $and: [{ id: 1 }] };
let f3: MongoFilter<Person> = { id: 1 };

// should not compile
let w1: MongoFilter<Person> = { wrong: 1 }; // does not compile - good
let w2: MongoFilter<Person> = { $or: [{ wrong: 1 }] }; // compiles

Expected behavior:
Code below should not compile

let w1: MongoFilter<Person> = { $or: [{ wrong: 1 }] };

Actual behavior:
But it does

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions