type Strings = [string, string];
type Numbers = [number, number];
// [string, string, number, number]
type StrStrNumNum = [...Strings, ...Numbers];
A rest element must be last in a tuple type.
type Strings = [string, string];
type Numbers = number[];
// [string, string, ...Array<number | boolean>]
type Unbounded = [...Strings, ...Numbers, boolean];
function partialCall(f, ...headArgs) {
return (...tailArgs) => f(...headArgs, ...tailArgs);
}
type Arr = readonly unknown[];
function partialCall<T extends Arr, U extends Arr, R>(
f: (...args: [...T, ...U]) => R,
...headArgs: T
) {
return (...b: U) => f(...headArgs, ...b);
}
const foo = (x: string, y: number, z: boolean) => {};
// This doesn't work because we're feeding in the wrong type for 'x'.
const f1 = partialCall(foo, 100);
// ~~~
// error! Argument of type 'number' is not assignable to parameter of type 'string'.
// This doesn't work because we're passing in too many arguments.
const f2 = partialCall(foo, "hello", 100, true, "oops");
// ~~~~~~
// error! Expected 4 arguments, but got 5.
// This works! It has the type '(y: number, z: boolean) => void'
const f3 = partialCall(foo, "hello");
// What can we do with f3 now?
f3(123, true); // works!
f3();
// error! Expected 2 arguments, but got 0.
f3(123, "hello");
// ~~~~~~~
// error! Argument of type '"hello"' is not assignable to parameter of type 'boolean'
function foo(...args: [string, number]): void {
// ...
}
function foo(arg0: string, arg1: number): void {
// ...
}
type Range = [start: number, end: number];
type Foo = [first: number, second?: string, ...rest: any[]];
class Square {
sideLength;
constructor(sideLength: number) {
if (Math.random()) {
this.sideLength = sideLength;
}
}
get area() {
return this.sideLength ** 2;
// ~~~~~~~~~~~~~~~
// error! Object is possibly 'undefined'.
}
}
class Square {
// definite assignment assertion
// v
sideLength!: number;
// ^^^^^^^^
// type annotation
constructor(sideLength: number) {
this.initialize(sideLength);
}
initialize(sideLength: number) {
this.sideLength = sideLength;
}
get area() {
return this.sideLength ** 2;
}
}
a &&= b; // a = a && b
a ||= b; // a = a || b
a ??= b; // a = a ?? b
try {
// ...
} catch (e) {
// error!
// Property 'toUpperCase' does not exist on type 'unknown'.
console.log(e.toUpperCase());
if (typeof e === "string") {
// works!
// We've narrowed 'e' down to the type 'string'.
console.log(e.toUpperCase());
}
}
// Note: these pragma comments need to be written
// with a JSDoc-style multiline syntax to take effect.
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from "preact";
let stuff = (
<>
<div>Hello</div>
</>
);
// Note: these pragma comments need to be written
// with a JSDoc-style multiline syntax to take effect.
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from "preact";
let stuff = h(Fragment, null, h("div", null, "Hello"));