镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

"Object literal may only specify known properties" doesn't work on arrays #52219

Closed

Description

@Juknum

Bug Report

🔎 Search Terms

conditional typings vscode discriminated union

🕗 Version & Regression Information

  • This seems to be an unintended behavior of the compiler.
  • This is the behavior in every version I tried (Latest release & nightly), and I reviewed the FAQ for entries about

⏯ Playground Link

type TextureUse =
  | { edition: "bedrock" | "dungeons" }
  | { edition: "java"; type: "resource_pack"; assets: string }
  | { edition: "java"; type: "texture_pack" };

let uses: TextureUse[] = [
    {
      edition: "java",
      type: "texture_pack",
      assets: "foo",
      // OK, the error was expected
    },
    {
      edition: "java",
      type: "resource_pack",
      assets: "minecraft",
    },
    {
      edition: "bedrock",
      type: "resource_pack" 
      // NOT OK,
      // -> Shouldn't be allowed as TextureUse doesn't have a definition 
      //    for `type` when `edition` === "bedrock" | "dungeons"
    }
]
Output
"use strict";
let uses = [
    {
        edition: "java",
        type: "texture_pack",
        assets: "foo",
        // OK, the error was expected
    },
    {
        edition: "java",
        type: "resource_pack",
        assets: "minecraft",
    },
    {
        edition: "bedrock",
        type: "resource_pack"
        // NOT OK,
        // -> Shouldn't be allowed as TextureUse doesn't have a definition 
        //    for `type` when `edition` === "bedrock" | "dungeons"
    }
];
Compiler Options
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2017",
    "jsx": "react",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}

Playground Link: Provided

💻 Code

// See the above playground code

🙁 Actual behavior

Visual Studio Code & The playground doesn't errors when unknown property is specified

🙂 Expected behavior

Object literal may only specify known properties should be thrown?

Activity

  1. Juknum commented on Jan 13, 2023

    @Juknum
    Author

    On the community discord we found out a workaround :

    . type TextureUse =
    -   | { edition: "bedrock" | "dungeons" }
    +   | { edition: "bedrock" | "dungeons", type?: never }
    .   | { edition: "java"; type: "resource_pack"; assets: string }
    .   | { edition: "java"; type: "texture_pack" };

    Then trying to assign anything to type will throw an error letting only one possibility : do not declare it.

    image

  2. RyanCavanaugh commented on Jan 14, 2023

    @RyanCavanaugh
    Member

    This runs into limitations of the current excess property detection logic. When the target is a union, TS needs to find which type in the union is the one that should be used to mark properties as excess. The part of the algorithm that normally works here is to find the union discriminant, which is almost edition here, but not quite, because there's more than one type with edition: "java". So EPC says "Well, there doesn't seem to be an obvious target type here".

    When no such type can be found, the fallback behavior is that any property from any type in the union is valid, which is what's happening here.

  3. RyanCavanaugh commented on Jan 14, 2023

    @RyanCavanaugh
    Member

    If someone can concoct a PR that can fix this without perf downside we'd take it, otherwise this might just be a "wait for exact types" thing.

  4. Juknum commented on Jul 4, 2023

    @Juknum
    Author

    Seems to have been fixed in 5.1.3 & 5.2.0-dev.20230704 👀

  5. jakebailey commented on Jul 5, 2023

    @jakebailey
    Member

    The fix bisects to #51884. Seems like that's intentional and good? I think the tests cover this?

  6. jakebailey commented on Jul 6, 2023

    @jakebailey
    Member

    I'm gonna vote yes 😄

  7. Juknum commented on Jul 6, 2023

    @Juknum
    Author

    Oops yeah I wasn't sure if your answer was for me or somebody else ^^"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions