Closed zirkelc closed 1 year ago
Also when I try to export the state machine to a single file it fails with:
Cannot load "serverless.ts": Initialization error: TSError: ⨯ Unable to compile TypeScript:
serverless.ts:650:7 - error TS2322: Type '{ events: { schedule: { rate: string; enabled: boolean; }; }[]; dependsOn: string[]; definition: { StartAt: string; States: { "Add empty LastEvaluatedKey": { Type: string; Next: string; Result: { LastEvaluatedKey: string; }; ResultPath: string; }; ... 4 more ...; "Add new LastEvaluatedKey": { ...; }; }; }; }' is not assignable to type '{ id?: string; name?: string; events?: any; dependsOn?: any; definition: Definition; tracingConfig?: TracingConfig; }'.
The types of 'definition.States' are incompatible between these types.
Type '{ "Add empty LastEvaluatedKey": { Type: string; Next: string; Result: { LastEvaluatedKey: string; }; ResultPath: string; }; Scan: { Type: string; Next: string; Parameters: { TableName: { Ref: string; }; FilterExpression: string; ExpressionAttributeNames: { ...; }; ExpressionAttributeValues: { ...; }; "ExclusiveStart...' is not assignable to type 'States'.
Property '"Add empty LastEvaluatedKey"' is incompatible with index signature.
Type '{ Type: string; Next: string; Result: { LastEvaluatedKey: string; }; ResultPath: string; }' is not assignable to type 'Choice | Fail | Map | Task | Parallel | Pass | Wait | Succeed'.
Type '{ Type: string; Next: string; Result: { LastEvaluatedKey: string; }; ResultPath: string; }' is not assignable to type 'Pass'.
Types of property 'Type' are incompatible.
Type 'string' is not assignable to type '"Pass"'.
650 addCredits,
~~~~~~~~~~
node_modules/serverless-step-functions/lib/index.d.ts:13:3
13 [stateMachine: string]: {
~~~~~~~~~~~~~~~~~~~~~~~~~
14 id?: string;
~~~~~~~~~~~~~~~~
...
19 tracingConfig?: TracingConfig;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 };
~~~~
The expected type comes from this index signature.
Also when I try to export the state machine to a single file it fails with:
What do you mean with exporting it to a single file? The types use module augmentation to merge the types into the official AWS type:
If you want to use the types as stand-alone, we should probably export the stepFunctions
type separately.
Is that what you mean?
Also when I try to export the state machine to a single file it fails with:
What do you mean with exporting it to a single file? The types use module augmentation to merge the types into the official AWS type:
If you want to use the types as stand-alone, we should probably export the
stepFunctions
type separately.Is that what you mean?
Nope. What I wanted to have in a different file is the stateMachine implementation. Not the types. So I can have a file for each StateMachine and split things so I don't have a huge serverless.ts file.
I've also found that we are missing type?: 'STANDARD' | 'EXPRESS';
and loggingConfig?: any;
( https://github.com/serverless-operations/serverless-step-functions/issues/281 )
Also when I try to export the state machine to a single file it fails with:
What do you mean with exporting it to a single file? The types use module augmentation to merge the types into the official AWS type: https://github.com/serverless-operations/serverless-step-functions/blob/c464dcdc0e0255cd93170486c7fd907b9893c020/lib/index.d.ts#L3-L10
If you want to use the types as stand-alone, we should probably export the
stepFunctions
type separately. Is that what you mean?Nope. What I wanted to have in a different file is the stateMachine implementation. Not the types. So I can have a file for each StateMachine and split things so I don't have a huge serverless.ts file.
Yes, I think the issue wouldn't appear if you could type your stateMachine like this:
export const stateMachine1: StateMachine = {
// ...
};
I assume the issue is related to type widening by TypeScript. So the last error message as an example:
Types of property 'Type' are incompatible. Type 'string' is not assignable to type '"Pass"'.
The state machine expects type
to be a string literal of Pass
or Task
etc. But when you define your state machine outside of the serverless type, TypeScript widens the type from literal Pass
to string
. That causes the type error I guess.
I assume the issue is related to type widening by TypeScript. So the last error message as an example:
Types of property 'Type' are incompatible. Type 'string' is not assignable to type '"Pass"'.
The state machine expects
type
to be a string literal ofPass
orTask
etc. But when you define your state machine outside of the serverless type, TypeScript widens the type from literalPass
tostring
. That causes the type error I guess.
Ok, I didn't know the term or what was really happening but that's exactly the issue. Then what we could do is export the single type StateMachine
Everything is working from my side. Not sure if we are missing anything.
Edit: A few updates.
@horike37 could you please take a look if you have the chance. If you prefer not to include TS types in this package, we can move this PR to the DefinitelyTyped repo.
@zirkelc Thank you for this PR! Adding the type system should be really important. But right now we can't regularly maintain this repo, so it would be great if you can move this PR to the DefinitelyTyped repo.
@horike37 thanks for you reply! Alright, I'll submit a PR to DefinitelyTyped in the next few days.
@ebisbe I created a new PR in the DefinetlyTyped repo: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/66693
I didn't try it yet, but I think to get the types merged from this package, we have to use module augmentation in our serverless.ts
file directly:
import type { AWS } from '@serverless/typescript';
import type { StepFunctions } from 'serverless-step-functions';
declare module '@serverless/typescript' {
interface AWS {
stepFunctions?: StepFunctions;
}
}
we have to use module augmentation
I don't know what's that it. I will try to help you on the other PR.
It means add types from package serverless-step-functions
into the base types of @serverless/typescript
. However, I figured out that type packages can install other type packages. So we get it to work without add this part at the top:
import type { AWS } from '@serverless/typescript';
import type { StepFunctions } from 'serverless-step-functions';
declare module '@serverless/typescript' {
interface AWS {
stepFunctions?: StepFunctions;
}
}
We have to wait for the approval on the DT repo.
Ok. What I don't like on this PR is that we have been doing it manually... It would be perfect if we could extract the full state machine definition and convert it to types so it can be automated. Here it's for CF resources https://github.com/awboost/cfntypes ( only sadly )
Yes, I totally agree! Unfortunately, there is no official JSON schema that we can rely on. The official spec doesn't publish any specification: https://states-language.net/spec.html
There is this package that provides validation for ASL: https://github.com/ChristopheBougere/asl-validator
It has some JSON schemas for the actual states: https://github.com/ChristopheBougere/asl-validator/tree/main/src/schemas It could be possible to generate TS types from these files, but I didn't check if it's complete.
It might be possible to generate the types with this package https://www.npmjs.com/package/json-schema-to-typescript
@zirkelc this package has a validation option. Let me see what is using under the hood.
EDIT: It's using "asl-validator": "^3.8.0", the package you mentioned.
This PR adds TypeScript types as discussed in #370
First, you need to use the official TypeScript @serverless/typescript package. for your
serverless.ts
file.TypeScript merges the types from this package with the base types from @serverless/typescript with either of these two options:
Add
/// <reference types="serverless-step-functions" />
at the top of yourserverless.ts
Add
"types": ["serverless-step-functions"]
to yourtsconfig.json
I can't guarantee that the types are fully complete and correct, but I think there are a good starting point.
If you rather prefer to have the types provided as a separate
@types/serverless-step-functions
package, I'd be willing to submit a PR to the DefinetlyTypes package.