microsoft / microsoft/TypeScript

Support custom typeof functions

オープン
#30,698 コメント 14 件 リアクション 2 件 担当者 0 名 GitHub で見る

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

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

説明

Search Terms

  • custom typeof
  • custom typeof function
  • custom type guard

Suggestion

When using a custom typeof‑like function, I’d like TypeScript compiler to be able to infer the correct type in the scope guarded by the custom typeof‑like function.

Use Cases

I need this to provide proper type information for the type function from Blissfuljs and similar projects.

The current approach requires defining the type(…) function as type(obj: any): string and then doing a type cast every time something is accessed within the if block:

/// <reference types="blissfuljs"/>
declare var something: any;
if ($.type(something) === "array") {
	(something as any[]).forEach(v => {/* stuff */})
}

Examples

type-func.d.ts
/**
 * @param obj The variable to check the type of.
 * @return The result of `typeof obj` or the class name in lowercase for objects.
 *         In the case of numbers, if the value is `NaN`, then the result is `nan`.
 */
declare function type(obj: null): "null";
declare function type(obj: undefined): "undefined";

// This is to ensure that the type system short-circuits when it encounters primitive types.
declare function type(obj: number): "number" | "nan";
declare function type(obj: string): "string";
declare function type(obj: symbol): "symbol";
declare function type(obj: boolean): "boolean";

// Needed to ensure proper return values when wrapper objects are used.
/* tslint:disable:ban-types */
declare function type(obj: number | Number): "number" | "nan";
declare function type(obj: string | String): "string";
declare function type(obj: symbol | Symbol): "symbol";
declare function type(obj: boolean | Boolean): "boolean";
declare function type(obj: Function): "function";
/* tslint:enable:ban-types */

declare function type(obj: any[]): "array";
declare function type(obj: RegExp): "regexp";
declare function type(obj: any): string;
export = type;

example.ts

import type = require("./type-func");
declare var something: any;

if (type(something) === "array") {
	// $ExpectType any[]
	something;
} else if (type(somthing) === "number") {
	// $ExpectType number
	something;
}

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 番号を参照したプルリクエストを送ります。

調査の方向性

まず、issue にある type-func.d.ts の宣言と example.ts の再現コードから始め、typeof チェックとユーザー定義の type guard に対して TypeScript がどのように narrowing を処理するかを調べます。示された比較が各分岐内でキャストなしに any[] と number を推論し、既存の JavaScript の出力と動作が維持されれば完了です。

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

評価

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

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

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