You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was writing a test that ensures marshalling/unmarshalling works as expected. The object being marshalled has an optional field that's a Uint8Array.
// for reasons the type is `{ foo?: Uint8Array }`constinput=createInput('some seemingly unrelated data')constmarshalled=marshal(input)constoutput=unmarshal(marshalled)// now do some assertions
if(!input.foo){thrownewError('input had no `foo`')}expect(output).to.have.property('foo').that.equalBytes(input.foo)
The reason being that the type of input.foo is Uint8Array | undefined and undefined is not compatible with string | ArrayLike<number>, so by doing if (!input.foo) and throwing we let tsc know that input.foo is a thing and therefore a Uint8Array and compatible with ArrayLike<number>.
This feels a bit weird because we're using chai to test some properties and tsc to test others, though it's really just a quirk of the type system.
Not sure I can see the analogy with Equal interface. The equalBytes argument is not the tested / actual value, it is the expected value. Expected value types are restricted in some Chai typings, e.g. length assertions (Length interface) take a number argument, not any. Making expected values untyped would defeat the purpose of typings, IMO.
In the case you provided, it seems that input.foo is not undefined (otherwise, the expect(input) assertion will fail), but the TypeScript type checker cannot infer that, unlike when the if short circuit is used. (IMO, it's unreasonable to expect the type checker to be this smart, but the root issue is there.) If the test is focused on marshalling, I'd say that running assertions on input is kind of weird, and using ifs instead could help separating test setup from assertions.
The types for
.equalBytes
are:I was writing a test that ensures marshalling/unmarshalling works as expected. The object being marshalled has an optional field that's a
Uint8Array
.What I'd like to do, and can do without types:
What I have to do with type checking:
The reason being that the type of
input.foo
isUint8Array | undefined
andundefined
is not compatible withstring | ArrayLike<number>
, so by doingif (!input.foo)
and throwing we lettsc
know thatinput.foo
is a thing and therefore aUint8Array
and compatible withArrayLike<number>
.This feels a bit weird because we're using
chai
to test some properties andtsc
to test others, though it's really just a quirk of the type system.Chai itself specifies values to be tested as
any
. If this module did the same thing it would allow much more concise tests.The text was updated successfully, but these errors were encountered: