microsoft / microsoft/TypeScript

Non‑`void` returning assertion functions

オープン
#40,562 コメント 11 件 リアクション 134 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.4k
平均マージ
1日 19時間
マージ済み PR(30日)
117

説明

Search Terms

  • assertion function non-void return type
  • assertion function non-void return
  • assertion function generic return
  • assertion function custom return

Suggestion

A way to type a function that is both an assertion function and returning a value that is not void.

Use Cases

This is necessary to correctly type Jest’s expect(…) matchers, which have a generic return type of R.

Examples

declare const expect: <T>(actual: T): JestMatchers<T>;

type JestMatchers<T> = JestMatchersShape<
	Matchers<void, T>,
	Matchers<
		Promise<void>,
		T extends PromiseLike<infer U>
			? U
			: Exclude<T, PromiseLike<any>>
	>
>;

type JestMatchersShape<TNonPromise extends {} = {}, TPromise extends {} = {}> = {
	resolves: AndNot<TPromise>;
	rejects: AndNot<TPromise>;
} & AndNot<TNonPromise>

type AndNot<T> = T & { not: T };

interface Matchers<R, T = {}> {
	toBe<E>(expected: E): R & (asserts T is E);
}

declare const foo: unknown;
expect(foo).toBe("foo");
foo; // $ExpectType "foo"
// Some typings for engine262's Completion Record handling:
type UnwrapNormalCompletion<T>
	= unknown extends T ? Value | undefined
	: T extends NormalCompletion<infer V>
		? (unknown extends V ? Value | undefined : V)
	: T extends Completion ? never
	: T;

/** @see https://tc39.es/ecma262/#sec-returnifabrupt */
export declare function ReturnIfAbrupt<T>(completion: T):
	(UnwrapNormalCompletion<T>)
	& (asserts completion is UnwrapNormalCompletion<T>);

/** @see https://tc39.es/ecma262/#sec-returnifabrupt-shorthands */
export { ReturnIfAbrupt as Q };

/**
 * The type signature is the same, but `AssertNormalCompletion` causes an error to be thrown at runtime
 * if `argument` is an AbruptCompletion, whereas `ReturnIfAbrupt` gets replaced with code that causes
 * the caller to return the AbruptCompletion by engine262's build system:
 *
 * @see https://tc39.es/ecma262/#sec-returnifabrupt
 * @see https://tc39.es/ecma262/#sec-returnifabrupt-shorthands
 */
declare function AssertNormalCompletion<T>(completion: T):
	(UnwrapNormalCompletion<T>)
	& (asserts completion is UnwrapNormalCompletion<T>);
export { AssertNormalCompletion as X };

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

実装ファイルやテストは指定されていません。まず、TypeScript に既存する assertion functions の処理と、Jest の matcher および completion records の例を確認してください。示されている型の絞り込みを維持したまま、void ではないジェネリックな戻り値を持つ assertion functions をサポートできれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
30/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。