type-fest icon indicating copy to clipboard operation
type-fest copied to clipboard

MergeExclusive is broken when used together with Except or built-in Omit

Open dev-natalya opened this issue 3 years ago • 3 comments

Environment

{
  "typescript": "4.2.4",
  "type-fest": "1.0.2"
}

Problem

MergeExclusive is broken when used together with Except or the built-in Omit

How to reproduce

import type * as TF from "type-fest"
type a = TF.MergeExclusive<{ a: boolean }, { b: boolean}> & { c: boolean }
type b = Omit<a, "c">

const c: b = {
  a: true,
  b: true
}

Screenshots

Click to see the screenshots Screen Shot 2021-04-16 at 7 41 42 PM Screen Shot 2021-04-16 at 7 43 15 PM

dev-natalya avatar Apr 16 '21 13:04 dev-natalya

Do you have "strict": true enabled in your TS config?

sindresorhus avatar Apr 16 '21 14:04 sindresorhus

@sindresorhus thank you for the reply. Yes, I do.

This is my tsconfig.json:

{
  "exclude": ["**/node_modules", "**/.git", "**/dist", "**/tmp"],

  "compilerOptions": {
    "noEmit": true,
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true,
    "allowJs": false,
    "checkJs": false,
    "skipLibCheck": true,

    "lib": ["esnext", "dom"],
    "module": "esnext",
    "target": "esnext",

    "sourceMap": true,
    "jsx": "react",
    "forceConsistentCasingInFileNames": true,
    "importHelpers": false,
    "resolveJsonModule": true,

    "strict": true,
    "noImplicitAny": false,
    "noUnusedLocals": false, // optimization happens during build
    "noUnusedParameters": false, // optimization happens during build

    "suppressImplicitAnyIndexErrors": true,

    "noEmitHelpers": true,
    "noErrorTruncation": true,
    "experimentalDecorators": true,

    "assumeChangesOnlyAffectDirectDependencies": true
  },

  "watchOptions": {
    // Use native file system events for files and directories
    "watchFile": "useFsEventsOnParentDirectory",
    "watchDirectory": "useFsEvents",

    // Poll files for updates more frequently
    // when they're updated a lot.
    "fallbackPolling": "dynamicPriority"
  }
}

dev-natalya avatar Apr 16 '21 16:04 dev-natalya

Hmm, this seems to me like a TypeScript limitation. It flattens the type when using Omit.

I have made a playground if anyone wants to help debug this: https://www.typescriptlang.org/play?ts=4.2.3&ssl=16&ssc=1&pln=16&pc=2#code/C4TwDgpgBA6glsAFgewK7ADwDE4CcDOwAKuBADRQDKEAxsgHYAmJkAfFALxQDeA2gNIQQLaHHpQAogA8aAG1SMIGANZDkAMyg4CxUhVUgNVWg2alWAXQD8ALij0IANwi4AvgG4AUJ9CQoAWRcAcwhpOVR8OGdsPEIRCmo6JhF2Dk8ASAAKbTjSKAAfYySzSABKKAgpYAgmfChkACMAK1pgKCsMrPgkNEwc3UgEk2TzKAAyItMRcsLM7pR0DESpvS1YgYh2Cf7pqBtOnbzC5ZHIL28fPIBDTgDg0Jl5SOjuKCu7BuRkWQgr8VcKK8Gh8vj8-q4tjwoDQQd9fv9Ln4GrcAPIAWwQGCuFAARDQcaxvElCNCPrduJ4oG87MBcKhyJSoMCoLT6Z5XEA

It might also be worth asking in https://github.com/Microsoft/TypeScript/issues/14094 where the type was inspired from.

sindresorhus avatar Apr 19 '21 09:04 sindresorhus

@natalya-kim @sindresorhus Seems to work with Except Playground.

skarab42 avatar Sep 15 '22 09:09 skarab42

@sindresorhus The PR #263 introduced in v2.3.2 fix the issue with Expect and MergeExclusive (Playground) and since Omit does not support it natively, there is nothing we can do, then I close this issue.

skarab42 avatar Sep 15 '22 09:09 skarab42