Typescript 2.2がでた。
変更点が少々あるので確認しておきたい。
Mixinのサポート
遂にMixinがサポートされた。やり方が少々直感的ではないけども。
公式のサンプルコードで確認する。
class Point { constructor(public x: number, public y: number) {} } class Person { constructor(public name: string) {} } type Constructor<T> = new(...args: any[]) => T; function Tagged<T extends Constructor<{}>>(Base: T) { // 今まではここでエラーになっていた。 return class extends Base { _tag: string; constructor(...args: any[]) { super(...args); this._tag = ""; } } } const TaggedPoint = Tagged(Point); let point = new TaggedPoint(10, 20); point._tag = "hello"; class Customer extends Tagged(Person) { accountBalance: number; } let customer = new Customer("Joe"); customer._tag = "test"; customer.accountBalance = 0;
上のコードのnew(...args: any[]) => T
がMixinのコンストラクタとして認識され、
Tagged
関数内で無名クラスでnew(...args: any[]) => T
を継承することが許されるようになった。
type Constructor<T> = new(...args: any[]) => T; function Loggable<T extends Constructor<{}>>(Target: T) { return class extends Target { protected log(content: string) {console.log(content)} } } class Base {} class Derived extends Loggable(Base) { public doSomething() { this.log('...'); } }
みたいにTrait的な感じで使える。
object型のサポート
今までのtypescriptはnumber | string | boolean | symbol | null | undefined
以外にPrimitive型を持っていなかったが、
今回からobject型が追加された。object型は上記のPrimitive型以外の全てに対応する。
これも公式のサンプルだが、
declare function create(o: object | null): void; create({ prop: 0 }); // OK create(null); // OK create(42); // Error create("string"); // Error create(false); // Error create(undefined); // Error
のような感じ、要はPrimitive以外を受け付けるanyのような感じか。
new.targetのサポート
new.targetがtypescriptでもサポートされた。
あまり使う機会は無いが、例ではErrorの継承があげられている。
class CustomError extends Error { constructor(message?: string) { super(message); // 'Error' breaks prototype chain here Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain } }
ErrorだけでなくArray等の、
constructorを単純に呼び出すだけではうまく継承できないビルトインクラスを継承する場合に使う。
null/undefinedチェックの強化
式中のnull/undefinedのチェックが強化された。
以下の場合はエラーになる。
- もし、
+
オペレーターのオペランドがnullableで、オペランドがstringでもanyでも無いとき。 - もし、
-, *, **, /, %, <<, >>, >>>, &, |, ^
のオペランドがnullableのとき。 - もし、
<, >, <=, >=, in
のオペランドがnullableのとき。 - もし、
instanceof
の右辺がnullableのとき。 - もし、
+, -, ~, ++, --
の単項がnullableのとき。
stringをキーにしたオブジェクトにドットでアクセスできるようになった
以下のような型
interface StringMap<T> { [x: string]: T; }
にたいしてドットでプロパティアクセスしてもOKになった。
var stringMap: StringMap; stringMap.foobar; // ok stringMpa['foobar']; // ok
jsxの子要素に対するspreadオペレーターがサポートされた。
これも公式の例を拝借
function Todo(prop: { key: number, todo: string }) { return <div>{prop.key.toString() + prop.todo}</div>; } function TodoList({ todos }: TodoListProps) { return <div> {...todos.map(todo => <Todo key={todo.id} todo={todo.todo} />)} //ここ! </div>; } let x: TodoListProps; <TodoList {...x} />
のように、直接子要素を展開する構文がサポートされた。
jsx: react-nativeがサポートされた
これはそのまま。
react-nativeでコンパイルすると、jsx構文がそのまま残った上でjsの拡張子になる。
まとめ
Mixinが嬉しい!