aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
2.98k stars 559 forks source link

Overloading confusion on `marshall` #6253

Closed alex-at-cascade closed 1 day ago

alex-at-cascade commented 1 week ago

Checkboxes for prior research

Describe the bug

Starting with 3.598.0 when calling marshall on a variable typed as a simple object, the following error is reported:

marshallTest.ts:12:3 - error TS2322: Type 'BMember' is not assignable to type 'Record<string, AttributeValue>'.
  Index signature for type 'string' is missing in type 'BMember'.

NOTE: the problem only occurs when using a typed variable. Having a literal object as the param directly still works fine. Also, the problem does NOT occur in 3.596.0 or before.

SDK version number

@aws-sdk/package-name@version, ...

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v18.18.2 "typescript": "^5.5.3"

Reproduction Steps

Try to compile this file, marshallTest.ts:

import { DynamoDB } from "@aws-sdk/client-dynamodb";
import { marshall } from "@aws-sdk/util-dynamodb";

const dynamoDB = new DynamoDB({});

const myItem = {
  foo: "bar",
};

const p = dynamoDB.putItem({
  TableName: "mytable",
  Item: marshall(myItem),
});

Observed Behavior

above error occurred

Expected Behavior

no error should occur

Possible Solution

probably something to do with the order of type declarations (it appears reordering has already been attempted several times)

Additional Information/Context

No response

kuhe commented 1 week ago

Could you make a reproduction repository of this? I don't get a compiler error with the example.

kuhe commented 1 week ago

marshall(myItem) in the example resolves to the signature

export declare function marshall(data: Map<string, NativeAttributeValue> | Record<string, NativeAttributeValue>, options?: marshallOptions): Record<string, AttributeValue>;

which matches the type of Item

alex-at-cascade commented 1 week ago

Your result is definitely what I was expecting. I wonder if my tsconfig.json would impact it?

{
  "compilerOptions": {
    "lib": ["es2020"],
    "module": "commonjs",
    "target": "es2020",
    "outDir": "build",
    "sourceMap": true,
    "importHelpers": true,
    "strict": true,
    "esModuleInterop": true,
    "allowJs": true,
    "resolveJsonModule": true
  },
  "exclude": ["node_modules"],
  "include": ["*.ts"]
}
kuhe commented 1 week ago

My test works with that tsconfig too, so you'll have to provide a reproduction sample repository.

ininrobu commented 1 week ago

I'm seeing this issue as well, though I don't have a concise reproduction handy. I believe the cause is this change: https://github.com/aws/aws-sdk-js-v3/pull/6195/files#diff-5cb8b8aa06642c3dd60ce3fd1ebdcd54c5258b790d3956fb1b6ade503b00654cL42 Specifically the fact that it reordered the marshal overloads and now has the NativeAttributeBinary variant before the others that would match complex objects. That type is a union including File which is basically anything, causing the incorrect signature match. They key here is the comment where File is declared - if your tsconfig does not include the DOM definitions then you'll hit this issue because File is such a wide-matching type. Adding DOM to the tsconfig lib works around the issue, but imo it's really an SDK bug.

kuhe commented 5 days ago

Should be fixed in today's release by PR #6261. The expected version is https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.614.0.