microsoft / microsoft/TypeScript
[3.5.0-dev.20190516] Incorrect type error for mixin
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.3k
- 平均マージ
- 2日 4時間
- マージ済み PR(30日)
- 132
説明
When using the mixin pattern, there are 2 main notations to define the type of the mixin entity.
The mixin pattern:
export type AnyFunction<A = any> = (...input : any[]) => A
export type AnyConstructor<A = object> = new (...input : any[]) => A
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>
export const Box = <T extends AnyConstructor<object>>(base : T) =>
class Box extends base {
value : any
}
1st notation:
export type Box = Mixin<typeof Box> {}
2nd notation:
export interface Box extends Mixin<typeof Box> {}
The 1st notation can not be used for recursive definitions (#29872). Because of that we primarily use 2nd notation. It works fine in most cases, however I found a case, when it produces invalid type error. The full snippet to reproduce the problem below.
Note:
- The typechecker correctly figures out that there's no
zxcproperty onthis, inside theobservemethod ofQuarkmixin. - In that method, it does not complain about the
this.valueusage - It does complain, when
valueis used on function argument - If you'll switch the
Quarkmixin to the 1st notation, the error will disappear
Expected behavior:
- No type errors for the definition of
testfunction below
export type AnyFunction<A = any> = (...input : any[]) => A
export type AnyConstructor<A = object> = new (...input : any[]) => A
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>
export const Box = <T extends AnyConstructor<object>>(base : T) =>
class Box extends base {
value : any
}
export interface Box extends Mixin<typeof Box> {}
export const Observable = <T extends AnyConstructor<object>>(base : T) =>
class Observable extends base {
observe () : Quark {
return
}
}
export interface Observable extends Mixin<typeof Observable> {}
export const Quark = <T extends AnyConstructor<Box & Observable>>(base : T) =>
class Quark extends base {
observe () : Quark {
// No error here!
this.value
// error: Error:(28, 14) TS2339: Property 'zxc' does not exist on type 'Quark'.
this.zxc
return
}
}
export interface Quark extends Mixin<typeof Quark> {}
const test = (a : Quark) => a.value // <-- Error:(35, 28) TS2339: Property 'value' does not exist on type 'Quark'.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、この issue にある完全な TypeScript reproducer をコンパイルし、2 つの Quark mixin 記法を比較します。checker が Quark 内および test 関数の引数上で継承された value プロパティをどのように解決するかを追跡します。2 つ目の記法で a.value に対する型エラーが発生せず、無効な this.zxc へのアクセスでは引き続きエラーが報告されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 52/100