microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.21k stars 12.51k forks source link

Type checking shows unexpected behavior when a function argument is defined with a partial object. #60543

Open umenosuke opened 4 days ago

umenosuke commented 4 days ago

šŸ”Ž Search Terms

function argument partial object index signatures

šŸ•— Version & Regression Information

What I've tried in the Playground

5.8.0-dev.20241119 5.6.3 <-- This is my development environment version 3.3.3

āÆ Playground Link

https://www.typescriptlang.org/play/?ts=5.8.0-dev.20241119#code/N4KABBYGYK4HYGMAuBLA9nMSCmBnJAFAIYBOA5rgFxiiR1gAWaZ2TLA-NfiSnGQNzhIAXwCUNIfTAIMuNABtsAOnnNi5XKMGT6Ael1hsADwAO2ZGAC8APkbNW9sClxgC3XmTAAfMPAAm2FC82H6iOnQycHKKKmqkFEpsDixa4ZCR0cqqZARIAJ5maFBg8biJ9kmpdMIgOjj4BLRSdixJ1ABERF1E7QA0OmLadE1SGUgl1MBgANoA1th5XEg8fAC61HAwALYARtgkYMJWEs307UlJ7dQAjAAM-ad07dtEL1dgdw-NwkPN+k7jVRoWYuGwtZLYJwuAibXb7by+OABIJwEJhU4ZBRZOLTc4VeztVZVZqYmLZXIFbBFEq4i4EomCU5pCD-ADCGGWpDyWDQhlM5iQRFQsl6YDgvP2JDQBzQCAQMBIuGZYH+AGUiFtIQB3FBIBhgdrigAKUrMJHyAEE5XhcAAxKVbACSSOMqpQZDgQoV2HaYFw2HGSF57SgRHk-vayvqhCIxIgNR0I3oYwmYAASuZpX4ADzuPii2F7Ei2SwnR4QPGtAk3e7Kp4vN41r5SH61U7-XVgIEgqy2OksKGuQvwnz+QLBULK0nYnJEWn4liEuPJ2RY2I5fKFYpzysQpeM5rKtkckhcnl8szIIXoKIFiUkKUyuUKpWnaPEZcJ4ZT2TjIjHJNTl3S4mzrSBni2V5IPeT5lVbH8ojXckd37H0GQQzJ1wpLcaWA+lUiPAxHWKPVIRMU19nyMUNUhZw-UvFAghCC95BQBBdXkPJRVIwwH2lMBZXlRUShcYxLxwPwlCjPAY0-EAaiAA

šŸ’» Code

{
    function test(args: {
        hogehoge?: string;
    }) {
        console.log(args);

        // expect => hogehoge is (string | undefined)
        console.log(args.hogehoge);
        console.log(typeof args.hogehoge);
    }

    test({
        hogehoge: "aaaa",
    });

    {
        const a: { [key: string]: number } = {
            "hogehoge": 10,
            "umauma": 10,
        };

        // it looks => hogehoge is (number | undefined)
        console.log(a["hogehoge"]);
        console.log(typeof a["hogehoge"]);

        // Contrary to expectations, no error occurs
        // Same with "noPropertyAccessFromIndexSignature" set to "false"
        test(a);
    }

    {
        const a: Record<string, number> = {
            "hogehoge": 10,
            "umauma": 10,
        };

        // it looks => hogehoge is (number | undefined)
        console.log(a["hogehoge"]);
        console.log(typeof a["hogehoge"]);

        // Contrary to expectations, no error occurs
        test(a);
    }

    {
        const a = {
            "hogehoge": 10,
            "umauma": 10,
        };

        console.log(a["hogehoge"]);
        console.log(typeof a["hogehoge"]);

        // If the property name is specified explicitly, the error occurs as expected.
        test(a);
    }
}

šŸ™ Actual behavior

See code comments above.

šŸ™‚ Expected behavior

See code comments above.

Additional information about the issue

When specifying a partial object as a function argument, it is possible to call the function with variables defined by index signatures (different types than the function argument).

Below is the tsconfig.json I am using

{
    "compilerOptions": {
        "declaration": true,
        "forceConsistentCasingInFileNames": true,
        "module": "ES2022",
        "noFallthroughCasesInSwitch": true,
        "noImplicitOverride": true,
        "noImplicitReturns": true,
        "noPropertyAccessFromIndexSignature": true,
        "noUncheckedIndexedAccess": true,
        "outDir": "./contents/build/",
        "removeComments": true,
        "rootDir": "./contents/src/",
        "skipLibCheck": true,
        "sourceMap": true,
        "strict": true,
        "target": "ES2022",
        "verbatimModuleSyntax": true
    }
}
jcalz commented 4 days ago

Duplicate of #27144

umenosuke commented 4 days ago

Thank you, it certainly seems similar to that issue. I will ask questions there from now on.