Skip to content

Shorthand function signature issues with IOPortManager #184

@axmmisaka

Description

@axmmisaka

Issue

In port.ts, if the following change is made according to ESLint suggestion:

interface IOPortManager<T> extends TriggerManager {
-  addReceiver(port: WritablePort<T>): void;
+  addReceiver: (port: WritablePort<T>) => void;
-  delReceiver(port: WritablePort<T>): void;
+  delReceiver: (port: WritablePort<T>) => void;
}

Then lingua-franca tests will fail, and __tests__/bank.ts will error.

Specifically, this.d.allWritable(this.d.port((member) => member.o)); will experience typing error. While tsc can correctly infer the lambda type to be function(member: MultiPeriodic): OutMultiPort<number>, it infers port to be Bank<MultiPeriodic, unknown>.port<Port<unknown> | MultiPort<unknown>>(selector: (reactor: MultiPeriodic) => Port<unknown> | MultiPort<unknown>): (Port<unknown> | MultiPort<unknown>)[]; the generic types are unknown instead of number`.

The issue specifically is

Type 'OutMultiPort<number>' is not assignable to type 'Port<unknown> | MultiPort<unknown>'.
      Type 'OutMultiPort<number>' is not assignable to type 'MultiPort<unknown>'.
        The types returned by 'channels()' are incompatible between these types.
          Type 'OutPort<number>[]' is not assignable to type 'IOPort<unknown>[]'.
            Type 'OutPort<number>' is not assignable to type 'IOPort<unknown>'.
              The types of 'asWritable(...).getPort().getManager(...).addReceiver' are incompatible between these types.
                Type '(port: WritablePort<number>) => void' is not assignable to type '(port: WritablePort<unknown>) => void'.
                  Types of parameters 'port' and 'port' are incompatible.
                    Type 'WritablePort<unknown>' is not assignable to type 'WritablePort<number>'.
                      The types returned by 'get()' are incompatible between these types.
                        Type 'unknown' is not assignable to type 'number | undefined'.

Failed LF tests include NestedMulti.ts where similar error message could be observed:

this._connectMulti([...this.b.port(it => it.y)], [this.x], false);
src/NestedBanks.ts(429,28): error TS2345: Argument of type '(Port<unknown> | MultiPort<unknown>)[]' is not assignable to parameter of type '(MultiPort<number> | IOPort<number>)[]'.
  Type 'Port<unknown> | MultiPort<unknown>' is not assignable to type 'MultiPort<number> | IOPort<number>'.
    Type 'Port<unknown>' is not assignable to type 'MultiPort<number> | IOPort<number>'.
      Type 'Port<unknown>' is missing the following properties from type 'IOPort<number>': get, asWritable, writer, manager
src/NestedBanks.ts(429,50): error TS2322: Type 'OutMultiPort<number>' is not assignable to type 'Port<unknown> | MultiPort<unknown>'.
  Type 'OutMultiPort<number>' is not assignable to type 'MultiPort<unknown>'.
    The types returned by 'channels()' are incompatible between these types.
      Type 'OutPort<number>[]' is not assignable to type 'IOPort<unknown>[]'.
        Type 'OutPort<number>' is not assignable to type 'IOPort<unknown>'.
          The types of 'asWritable(...).getPort().getManager(...).addReceiver' are incompatible between these types.
            Type '(port: WritablePort<number>) => void' is not assignable to type '(port: WritablePort<unknown>) => void'.
              Types of parameters 'port' and 'port' are incompatible.
                Type 'WritablePort<unknown>' is not assignable to type 'WritablePort<number>'.
                  The types returned by 'get()' are incompatible between these types.
                    Type 'unknown' is not assignable to type 'number | undefined'.

Based on my observation, a lot of Port-related places also requires type assertion to compile with error after this change. While I think these assertion are safe to make and it is okay to keep them, I think this is a situation that is worth attention.

See Also

#162
#175

microsoft/TypeScript#40855

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions