Hi @mvdbeek,
I think initially I misunderstood the assignment and wrote up the equivalent in TS code (shown here)
bio-cwl-tools/fastp/fastp.cwl at ts/fastp-poc · alexiswl/bio-cwl-tools (github.com)
I have noted however, this should be possible to auto-generate interfaces for TypeScript that emulate the cwl inputs and then wrap all the used JS expressions used in a CWL tool into functions that take in ‘inputs’ as a parameter where ‘inputs’ is of the type also defined by the autogenerated TS code? An example might help explain my rambling.
Part 1: Generate an inputs interface based on the inputs of the object. Note I’m using the rabix/cwlts library instead of cwl-ts-auto. I’ve explained a few differences here - TypeScript implementation makes FileTypes and DirectoryTypes difficult to work with · Issue #23 · common-workflow-lab/cwl-ts-auto (github.com)
// Author: Alexis Lucattini
// For assistance on generation of typescript expressions
// In CWL, please visit our wiki page at https://github.com/umccr/cwl-ica/wiki/TypeScript
// Imports
import {File as IFile} from "cwlts/mappings/v1.0/File"
import {Directory as IDirectory} from "cwlts/mappings/v1.0/Directory"
// Backward compatibility with --target es5
declare global {
interface Set<T> {
}
interface Map<K, V> {
}
interface WeakSet<T> {
}
interface WeakMap<K extends object, V> {
}
}
// Input types
export interface IFastpInputs {
fastq1: IFile
fastq2?: IFile
threads: number
qualified_phred_quality: number
unqualified_phred_quality: number
min_length_required: number
force_polyg_tail_trimming?: boolean
disable_trim_poly_g: boolean
base_correction: boolean
}
Part 2 - wrap the JS snippets into functions where inputs is a single parameter. You could in theory have other CWL JS attributes in as parameters such as runtime
.
// (Hypothetical) Auto-generated code when doing js validation
// valueFrom: $(inputs.fastq1.nameroot).fastp.fastq
function evaluate_line_17_value_from_js_statement(inputs: IFastpInputs){
return inputs.fastq1.nameroot
}
Then run tsc my-file.ts
Should return blank.
However, now let’s assume fastq1 in line 17 was accidentally references as fastq3 (as per your example above).
// (Hypothetical) Auto-generated code when doing js validation
// valueFrom: $(inputs.fastq3.nameroot).fastp.fastq
function evaluate_line_17_value_from_js_statement(inputs: IFastpInputs){
return inputs.fastq3.nameroot
}
tsc fastp-testing.ts
Instead now gives us:
fastp-testing.ts:43:19 - error TS2551: Property 'fastq3' does not exist on type 'IFastpInputs'. Did you mean 'fastq1'?
43 return inputs.fastq3.nameroot
~~~~~~
fastp-testing.ts:25:5
25 fastq1: IFile
~~~~~~
'fastq1' is declared here.
Found 1 error in fastp-testing.ts:43
Autogenerating TS from CWL shouldn’t be too difficult, particularly advances doen with the cwl-utils package. I use this to generate TypeScript interfaces for the various CWL schemas I create so I can then validate any JavaScript that interacts with the schemas (which I write that JavaScript in TypeScript now anyway - but use the Schema Interfaces for this purpose).