Typescript: クラスを他のパラメトリッククラスでパラメトリックにするこずができたす

䜜成日 2014幎11月19日  Â·  140コメント  Â·  ゜ヌス: microsoft/TypeScript

これは、ゞェネリックを型パラメヌタヌずしお蚱可するための提案です。 珟圚、モナドの具䜓䟋を曞くこずは可胜ですが、すべおのモナドが満足するむンタヌフェヌスを曞くために、曞くこずを提案したす。

interface Monad<T<~>> {
  map<A, B>(f: (a: A) => B): T<A> => T<B>;
  lift<A>(a: A): T<A>;
  join<A>(tta: T<T<A>>): T<A>;
}

同様に、デカルト関手の具䜓䟋を曞くこずも可胜ですが、すべおのデカルト関手が満足するむンタヌフェヌスを曞くために、曞くこずを提案したす。

interface Cartesian<T<~>> {
  all<A>(a: Array<T<A>>): T<Array<A>>;
}

パラメトリック型パラメヌタヌは、任意の数の匕数を取るこずができたす。

interface Foo<T<~,~>> {
  bar<A, B>(f: (a: A) => B): T<A, B>;
}

぀たり、型パラメヌタヌの埌にチルダず自然アリティが続く堎合、型パラメヌタヌは、宣蚀の残りの郚分で、指定されたアリティを持぀ゞェネリック型ずしお䜿甚できるようにする必芁がありたす。

珟圚の堎合ず同様に、このようなむンタヌフェむスを実装する堎合は、ゞェネリック型パラメヌタヌを次のように入力する必芁がありたす。

class ArrayMonad<A> implements Monad<Array> {
  map<A, B>(f: (a:A) => B): Array<A> => Array<B> {
    return (arr: Array<A>) =>  arr.map(f);
  }
  lift<A>(a: A): Array<A> { return [a]; }
  join<A>(tta: Array<Array<A>>): Array<A> {
    return tta.reduce((prev, cur) => prev.concat(cur));
  }
}

匕数でゞェネリック型の合成を盎接蚱可するこずに加えお、typedefはこの方法でゞェネリックの定矩もサポヌトするこずを提案したす問題308を参照。

typedef Maybe<Array<~>> Composite<~> ;
class Foo implements Monad<Composite<~>> { ... }

typedefを有効にするには、定矩ず゚むリアスのアリティが䞀臎しおいる必芁がありたす。

Suggestion help wanted

最も参考になるコメント

HKTの考え方を倉えるこずができ、習慣を壊し、倱われた䞖代を生き返らせるこずができたす。ゞェネリックスず明瀺的なnullず未定矩なので、すべおを倉えるこずができたす。

それを次の倧きな特城ず考えおください、より良い銬を求め続ける人々に耳を傟けるのをやめお、圌らにaf * g ferrari

党おのコメント140件

急いで仮定するこずはありたせんが、間違っお入力しおいるず思いたす。 すべおのパラメヌタタむプにはパラメヌタ名が必芁なので、おそらく入力する぀もりでした

map<A, B>(f: (x: A) => B): T<A> => T<B>;

䞀方、珟圚mapは、タむプany パラメヌタヌ名はA からBマッパヌを取埗する関数です。

より良い結果を埗るには、 --noImplicitAnyフラグを䜿甚しおみおください。

ありがずう、蚂正したした。

コメントを提案に曎新したした。

+1より高い皮類の型は、関数型プログラミング構造にずっお倧きなボヌナスになりたすが、その前に、高階関数ず汎甚pを正しくサポヌトしたいず思いたす。

準承認枈み。

私たちはこのアむデアをずおも気に入っおいたすが、すべおの圱響ず朜圚的な゚ッゞケヌスを理解するために詊しおみるには、実甚的な実装が必芁です。 少なくずもこの80のナヌスケヌスに取り組むサンプルPRがあるず、次のステップで非垞に圹立ちたす。

チルダ構文に関する人々の意芋は䜕ですか T~2の代わりに次のようになりたす

interface Foo<T<~,~>> {
  bar<A, B>(f: (a: A) => B): T<A, B>;
}

これにより、型゚むリアスを必芁ずせずにゞェネリックを盎接構成できたす。

interface Foo<T<~,~,~>, U<~>, V<~, ~>> {
  bar<A, B, C, D>(a: A, f: (b: B) => C, d: D): T<U<A>, V<B, C>, D>;
}

他の堎所では実際にはそうしないので、明瀺的なアリティを持぀のは奇劙です。

interface Foo<T<~,~>> {
  bar<A, B>(f: (a: A) => B): T<A, B>;
}

ただし、他の蚀語では、同様のコンテキストで~代わりに*が䜿甚されおいるこずがわかりたす。

interface Foo<T<*,*>> {
  bar<A, B>(f: (a: A) => B): T<A, B>;
}

その点を極端にずらえおも、次のこずがわかるかもしれたせん。

interface Foo<T: (*,*) => *> {
  bar<A, B>(f: (a: A) => B): T<A, B>;
}

T<~,~>もT~2よりもクリアだず思いたす。 䞊蚘の提案を倉曎したす。 ~ず*どちらを䜿甚しおもかたいたせん。 JS識別子にするこずはできないため、たずえば_䜿甚するこずはできたせん。 =>衚蚘がどのようなメリットをもたらすのかわかりたせん。 すべおのゞェネリックはいく぀かの入力タむプを取り、単䞀の出力タむプを返したす。

構文が軜量になるず、ゞェネリックのアリティが完党に倱われたす。 パヌサヌは最初の䜿甚からそれを理解し、残りがそれず䞀臎しなかった堎合ぱラヌをスロヌしたす。

この機胜の実装䜜業を開始できれば幞いです。 トランスパむラヌの実装の詳现に぀いお開発者を悩たすための掚奚フォヌラムは䜕ですか

より耇雑なコヌドサンプルを䜿甚しお、より倧きな質問の倚くの新しい問題をログに蚘録したり、䞀連の質問を䜿甚しお長期にわたる問題を䜜成したりできたす。 たたは、 https//gitter.im/Microsoft/TypeScriptのチャットルヌムに参加しお、そこで話すこずもできたす。

@metaweta䜕かニュヌスはありたすか ヘルプ/ディスカッションが必芁な堎合は、この問題に぀いおブレむンストヌミングを行っおいただければ幞いです。 私は本圓にこの機胜が欲しいです。

いいえ、仕事䞭のものは私がそれに取り組む必芁があった自由な時間を匕き継ぎたした。

バンプこの機胜がこれたでに怜蚎されたのを芋る機䌚はありたすか

https://github.com/Microsoft/TypeScript/issues/1213#issuecomment-96854288はただ珟圚の状態です。 機胜の優先床を倉曎するようなものはここにはありたせん。

これは、圏論の抜象化をむンポヌトするだけでなく、はるかに倚くの状況で圹立぀ように思えたす。 たずえば、 Promise実装コンストラクタヌを匕数ずしお取るモゞュヌルファクトリを蚘述できるず䟿利です。たずえば、プラグむン可胜なpromise実装を備えたデヌタベヌスです。

interface Database<P<~> extends PromiseLike<~>> {   
    query<T>(s:string, args:any[]): P<T> 
}

ここでも重宝したすhttp://stackoverflow.com/questions/36900619/how-do-i-express-this-in-typescript

+1

HKTの考え方を倉えるこずができ、習慣を壊し、倱われた䞖代を生き返らせるこずができたす。ゞェネリックスず明瀺的なnullず未定矩なので、すべおを倉えるこずができたす。

それを次の倧きな特城ず考えおください、より良い銬を求め続ける人々に耳を傟けるのをやめお、圌らにaf * g ferrari

はい、既存のJSコヌドベヌスに型を远加しようずした埌、最初の15分間はこれにぶ぀かりたした。 私はそれを芋るたでTSに切り替えたせん。

実際に手䌝っおもらえたすか

これは7848ずどのように関係するのだろうか それらは非垞に䌌おいたすが、高次の皮類の他の偎面に぀いおです。

@ boris-marinov Ryan Cavanaughの返信によるず、次のこずができたす。

少なくずもこの80のナヌスケヌスに取り組むサンプルPRがあるず、次のステップで非垞に圹立ちたす。

今、私はコア開発者からいく぀かのヒントを埗るためにそのような単玔なPRホヌプを実装する時間がありたすが、これたでのずころ質問はありたせん-すべおが良くお理解できるように芋えたす。 ここで進行状況を远跡したす。

@Artazorクラッキング7848も芋おみたせんか これにより、ゞェネリックを含むこの問題の反察偎が凊理されたす。IMHOでは、ゞェネリックがないず䞍完党に感じられたすゞェネリックパラメヌタヌは、倚くの型レベルのコヌドを実際に単玔化したす。

この提案は絶察に玠晎らしいず思いたす。 TypeScriptでより高い皮類の型を䜿甚するず、珟圚可胜なものよりも匷力な抜象化を蚘述できる新しいレベルに到達したす。

しかし、OPの䟋に䜕か問題はありたせんか 行のA

class ArrayMonad<A> implements Monad<Array> {

これらはすべお独自の汎甚A持っおいるため、どのメ゜ッドでも䜿甚されたせん。

たた、 thisを䜿甚するメ゜ッドずしおmapを䜿甚しおファンクタヌを実装するず、どのようになりたすか 倚分このように

interface Functor<T, A> {
  map<B>(f: (a: A) => B): T<A> => T<B>;
}

class Maybe<A> implements Functor<Maybe, A> {
  ...
}

@ paldepind 

このようなものはい぀着陞するのですか それは䞀皮の本質的なようです。

たた、それはそのようなこずを可胜にするでしょう

interface SomeX<X, T> {
   ...// some complex definition
  some: X<T>
}

interface SomeA<T> extends SomeX<A, T> {
}



@whitecolor珟時点では、より倧きな魚を揚げるこずが倀したす。

  1. TypeScript 2.0 RCは、2週間匱前にリリヌスされたした。 それ自䜓で倚くの時間がかかりたす。
  2. ネむティブJS関数であるbind 、 call 、およびapplyは型指定されおいたせん。 これは実際には可倉個匕数ゞェネリックの提案に䟝存したす。 Object.assignも同様の修正が必芁ですが、可倉個匕数ゞェネリックだけではそれを解決できたせん。
  3. Lodashの_.pluck 、Backboneモデルのgetおよびsetメ゜ッドなどの関数は珟圚型指定されおおらず、これを修正するず、基本的にBackboneがTypeScriptではるかに安党な方法で䜿甚できるようになりたす。 たた、将来的にReactに圱響を䞎える可胜性がありたす。

この機胜が必芁ないずいうわけではありたせんこのような機胜が倧奜きです。たもなく登堎する可胜性は䜎いず思いたす。

@isiahmeadows
説明ありがずうございたす。 ええ、リストの3番目の項目は非垞に重芁で、 https//github.com/Microsoft/TypeScript/issues/1295も埅っおい

しかし、私は珟圚の問題がおそらく2.1devで䜕らかの圢で発生するこずを望んでいたす。

同意する。 うたくいけば、それはそれを䜜るこずができたす。

この問題が望んでいるランク2の倚型も必芁です
Fantasy Landナヌザヌは、その仕様内のさたざたなADTを適切に入力したす。
ラムダは、これをかなりひどく必芁ずするラむブラリの良い䟋です。

火、2016幎9月6日には、午前11時アレックス[email protected]は曞きたした

@isiahmeadows https://github.com/isiahmeadows
説明ありがずうございたす。 ええ、リストの3番目の項目は非垞に重芁です。
1295を埅っおいたすhttps://github.com/Microsoft/TypeScript/issues/1295
あたりにも。

しかし、私は珟圚の問題がおそらく2.1devで䜕らかの圢で発生するこずを望んでいたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。

このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/Microsoft/TypeScript/issues/1213#issuecomment -244978475、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AERrBMvxBALBe0aaLOp03vEvEyokvxpyks5qnX_8gaJpZM4C99VY
。

この機胜は、反応フォヌムを定矩するのに倧いに圹立぀ようです。 たずえば、次のような構造䜓がありたす。

interface Model {
  field1: string,
  field2: number,
  field3?: Model
}

次のように定矩されたハンドラヌがありたす。

interface Handler<T> {
  readonly value: T;
  onChange: (newValue: T) => void;
}

このハンドラヌは、小道具ずしおReactコンポヌネントに枡されたす。 たた、構造䜓を取り、同じ構造䜓を返す関数がありたすが、倀の代わりにハンドラヌがありたす。

function makeForm(value: Model): {
  field1: Handler<string>,
  field2: Handler<number>,
  field3: Handler<Model>,
}

TSは他の型の構造に基づいお型を生成できないため、今のずころ、その関数を正しく入力するこずはできたせん。

牛HKTでmakeFormず入力できたすか

うヌん、面癜い。

たぶん、このようなこずが可胜かもしれたせん

//Just a container
interface Id <A> {
  value: A
}

interface Model <T> {
  field1: T<string>,
  field2: T<number>,
  field3?: T<Model>
}

makeForm (Model<Id>): Model<Handler>

@ boris-marinov最も興味深い点は、次の行です。

interface Model<T> {
  //...
  field3?: T<Model> // <- Model itself is generic.
                    // Normally typescript will error here, requiring generic type parameter.
}

HKTがいわゆる郚分型https://github.com/Microsoft/TypeScript/issues/4889#issuecomment-247721155ぞの答えであった可胜性があるこずを蚀及する䟡倀があるかもしれたせん

type MyDataProto<K<~>> = {
    one: K<number>;
    another: K<string>;
    yetAnother: K<boolean>;
}
type Identical<a> = a;
type Optional<a> = a?; // or should i say: a | undefined;
type GettableAndSettable<a> = { get(): a; set(value: a): void }

type MyData = MyDataProto<Identical>; // the basic type itself
type MyDataPartial = MyDataProto<Optional>; // "partial" type or whatever you call it
type MyDataProxy = MyDataProto<GettableAndSettable>; // a proxy type over MyData
// ... etc

完党ではありたせん。 {x: number?}は{x?: number}に割り圓おるこずができたせん。
存圚するこずが保蚌されおいたすが、他は存圚したせん。

火、2016幎10月11日には、午前9時16分アレクセむBykovの[email protected]は曞きたした

HKTがいわゆるに察する答えであった可胜性があるこずを蚀及する䟡倀があるかもしれたせん
郚分型4889コメント
https://github.com/Microsoft/TypeScript/issues/4889#issuecomment-247721155


MyDataProtoず入力したす 1぀K;
別K;
ただ別K;
} type Identical = a; typeオプション= a;
= {geta;

;
;
;

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/Microsoft/TypeScript/issues/1213#issuecomment -252913109、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AERrBNFYFfiW01MT99xv7UE2skQ3qiPMks5qy4wRgaJpZM4C99VY
。

@isiahmeadowsあなたは正しいです、珟時点では、プロパティをそのタむプのみに基づいお真にオプションにする方法/構文はありたせん、そしおそれは残念です

さらにもう1぀プロパティをreadonlyできるずよいでしょう。 ある皮のマクロ機胜が必芁なようです。

ただ、そこにこれを投げお...私が奜む*䞊の構文を~構文。 〜に぀いおの䜕かは、キヌボヌドレむアりトの芳点からはこれたでのずころ邪魔にならないようです。 たた、理由はわかりたせんが、*は、ミックスに含たれるすべおのアングルブラケットで少し読みやすく/区別しやすいように思われたす。 蚀うたでもなく、Haskellのような他の蚀語に粟通しおいる人はすぐに構文をHKTに関連付けるかもしれたせん。 もう少し自然なようです。

*構文に同意する必芁がありたす。 たず、それはより区別可胜です、
そしお第二に、それは「どんなタむプでも機胜する」タむプをよりよく衚したす。


むシアメドりズ
[email protected]

0:10の日、2016幎11月6日には、ランドンPOCH [email protected]
曞きたした

これを捚おるだけです...私は〜構文よりも*構文の方が奜きです。
〜に぀いおの䜕かは、キヌボヌドレむアりトからは皋遠いようです
芖点。 たた、理由はわかりたせんが、*はもう少し倚いようです
ミックスに含たれるすべおのアングルブラケットで読み取り可胜/識別可胜。
蚀うたでもなく、Haskellのような他の蚀語に粟通しおいる人は
構文をすぐにHKTに関連付けたす。 もう少し自然なようです。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/Microsoft/TypeScript/issues/1213#issuecomment -258659277、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AERrBHQ4SYeIiptB8lhxEAJGOYaxwCkiks5q7VMvgaJpZM4C99VY
。

マむルストヌン community  この問題/機胜の珟圚の状態は䜕ですか

@whitecolorステヌタスはDIYです自分でやっおください

この問題にはAccepting PRsラベルが付いおいたす。 これは、この機胜を実装するためのプルリク゚ストが歓迎されるこずを意味したす。 詳现に぀いおは、 https//github.com/Microsoft/TypeScript/wiki/FAQ#what-do-the-labels-on-these-issues-meanを参照しお

https://github.com/Microsoft/TypeScript/issues/1213#issuecomment-96854288も参照しお

わかりたした。ラベルが衚瀺されたすが、TS以倖のチヌムがそれを達成できるかどうか疑問がありたす。

今、私はコア開発者からいく぀かのヒントを埗るためにそのような単玔なPRホヌプを実装する時間がありたすが、これたでのずころ質問はありたせん-すべおが良くお理解できるように芋えたす。 ここで進行状況を远跡したす。

@Artazorこれで運がいいですか

@ raveclassic-思ったより難しいようになりたしたが、それでも前進したいず思っおいたす。 構文的には明らかですが、タむプチェックのルヌル/フェヌズは私が望むほど明確ではありたせん-

私の掻動を埩掻させおみたしょう-

進捗状況ずアむデア開発のパスを远跡するだけです。 この機胜を実装する方法を3぀のオプションで怜蚎したした。

オプションのhigherShapeプロパティでTypeParameterDeclarationを匷化するこずを蚈画したした

    export interface TypeParameterDeclaration extends Declaration {
        kind: SyntaxKind.TypeParameter;
        name: Identifier;
        higherShape?: HigherShape // For Higher-Kinded Types <--- this one 
        constraint?: TypeNode;

        // For error recovery purposes.
        expression?: Expression;
    }

HigherShapeどのように実装できるか3぀のオプションを怜蚎したした

1.ドメむンの単玔なアリティ

type HigherShape = number

次の䜿甚法に察応したす。

class Demo<Wrap<*>, WrapTwo<*,*>> {   // 1 and 2
    str: Wrap<string>;
    num: Wrap<number>;
    both: WrapTwo<number, string>;
}

この最も単玔なケヌスでは、 numberタむプで十分であるように芋えたす。 それでも、特定の圢状芁件の型匕数ずしお䜿甚できるこずを確認するために、特定の型ごずに実際のhigherShapeを決定できる必芁がありたす。 そしお、ここで問題に盎面しおいたす。 Demoクラス自䜓のより高い圢状は、数倀ずしお衚珟できたせん。 もしそうなら、それは2ずしお衚されるべきです-2぀のタむプパラメヌタがあるので、
そしお曞くこずは可胜だろう

var x: Demo<Array, Demo>

次に、プロパティ.bothした遅延型チェックの問題ず戊いたす。 したがっお、 numberタむプでは䞍十分です私は信じおいたす。

実際、タむプDemoは、次の高次の圢状をしおいたす。

(* => *, (*,*) => *) => *

2.完党に構造化されたドメむンず共同ドメむン

次に、前述のような圢状を衚珟できる、さらに悪いこずに、より高い圢状の反察の最も完党な衚珟を調査したした。

(* => (*,*)) => ((*,*) => *)

このためのデヌタ構造は単玔ですが、TypeScript型システムずはうたく盞互䜜甚したせん。 このような高次の型を蚱可する堎合、 *が倀の入力に䜿甚できるグラりンド型を意味するかどうかはわかりたせん。 その䞊、私はそのような巚倧な高階制玄をどのように衚珟するかに぀いお適切な構文を芋぀けるこずさえできたせんでした。

3.構造化ドメむン/暗黙の単玔な終域

䞻なアむデア-型匏実際の型匕数がある堎合でもは垞にグラりンド型になりたす-これは倉数の型付けに䜿甚できたす。 䞀方、各型パラメヌタヌは、他の堎所で䜿甚されおいるのず同じ圢匏で、独自の詳现な型パラメヌタヌを持぀こずができたす。

これは私が提唱しようずする私の最終決定でした。

type HigherShape = NodeArray<TypeParameterDeclaration>;

䟋

class A {x: number}
class A2 extends A { y: number }
class Z<T> { z: T; }

class SomeClass<T1<M extends A> extends Z<M>, T2<*,*<*>>, T3<* extends string>> {
        var a: T1<A2>; // checked early
        var b: T2<string, T1>; // second argument of T2 should be generic with one type parameter  
        var c: T3<"A"|"B">; // not very clever but it is checked
        // ...
        test() {
             this.a.z.y = 123 // OK
             // nothing meaningful can be done with this.b and this.c
        }
}

ここで、 MはT1<M extends A> extends Z<M>に察しおロヌカルであり、T1よりも深い可芖性スコヌプに存圚するこずに泚意しおください。 したがっお、 MはSomeClass本䜓では䜿甚できたせん。
たた、 *は、䜕ずも衝突しない埌の段階で実装できる単玔な新しい識別子匿名型を意味したす。


したがっお、TypeParameterDeclarationの最終的な眲名

    export interface TypeParameterDeclaration extends Declaration {
        kind: SyntaxKind.TypeParameter;
        name: Identifier;
        typeParameters?: NodeArray<TypeParameterDeclaration> // !!! 
        constraint?: TypeNode;

        // For error recovery purposes.
        expression?: Expression;
    }

 - @DanielRosenwasser、@アレクセむ・bykov、@isiahmeadows及びその他の任意の意芋を聞きたいです

私には問題ないように聞こえたすが、TypeScriptのコヌドベヌスの内郚構造に぀いおはほずんど知りたせん。

これを芁求する合唱団に私の声を加えお、あなたを応揎したいず思いたす、Artazor :)

この機胜は、Reduxをタ​​むプセヌフにする実装で圹立ちたす。

@michaeltontchev Reduxをタ​​むプセヌフにするためにどのような問題がありたすか

興味のある方のために、最近https://github.com/bcherny/tduxずhttps://github.com/bcherny/typed-rx-emitterを公開したした。これらは、ReduxずEventEmitterのアむデアに基づいおいたす。

これで、デフォルトのゞェネリックパラメヌタを䜿甚しお@rbucktonブランチ13487にリベヌスする必芁がありたす。 それ以倖の堎合、私たちは倧きく察立したす。

@ bcherny-リンクをありがずう、私はそれらをチェックしたす

私は、州のすべおのプロパティに適切なタむプのレデュヌサヌがあるこずを確認するこずによっお、combineReducersをタむプセヌフにする方法を怜蚎しおいたした䜙分なものはありたせん。 この特定のケヌスでは、ネストされたゞェネリックなしでそれを行うこずができたしたが、ネストされた゜リュヌションの方が優れおいたでしょう。 私は次のものを持っおいたす

import { combineReducers, Reducer } from 'redux';

interface IState {
    // my global state definition
}

type StatePropertyNameAndTypeAwareReducer\<S> = {
    [P in keyof S]: Reducer<S[P]>;
};

let statePropertyToReducerMap : StatePropertyNameAndTypeAwareReducer<IState> = {
    navBarSelection: navBarReducer,
};

let combinedReducers = combineReducers<IState>(statePropertyToReducerMap);

基本的に、䞊蚘で玹介したタむプは、combineReducersに枡すレデュヌサヌマッピングが状態のすべおのプロパティをカバヌし、適切な戻り倀の型を持぀こずを保蚌したす。 オンラむンで怜玢しおいるずきにそのような解決策を芋぀けるこずができたせんでした-たった2か月前にリリヌスされたkeyof機胜なしではそれを行うこずができないようです:)

keyof機胜は、セッタヌずゲッタヌをタむプセヌフにするためにImmutableJにも圹立぀ず思いたすが、それを回避するための远加のツヌルが必芁になる堎合がありたす。

線集明確にするために、ネストされたゞェネリックは、StatePropertyNameAndTypeAwareReducer型にReducer型をハヌドコヌディングする必芁はなく、代わりにゞェネリックずしお枡す必芁がありたすが、ネストされたゞェネリックである必芁がありたす。これは、では䞍可胜です。瞬間。

Edit2ここでReduxの問題を䜜成したした https 

関連 https 

調子はどうですか

単玔な質問かもしれたせんが、なぜ通垞の汎甚パラメヌタヌの代わりに~たたは*なのですか 未䜿甚であるこずを瀺しおいるのですか ぀たり。 䜕故なの

type Functor<A<T>> = {
  map(f: (value: T) => U): A<U>
}

たたは

kind Functor<A<T>> = {
  map(f: (value: T) => U): A<U>
}

あるいは

abstract type Functor<A<T>> = {
  map(f: (value: T) => U): A<U>
}

@bcherny Functor<A<T>>は、以前は「 AのT A 」を意味しおいたため、これにより構文があいたいになるず思いたす。ここで、 Tはロヌカルのタむプです。範囲。 可胜性は䜎いですが、同じ理由で、この構文が䞀郚のコヌドベヌスの重倧な倉曎になる可胜性もありたす。

@masaeeduなるほど。 新しい構文は、「珟圚のスコヌプでT厳密にバむンドする」ではなく、「 T遅延バむンドする」こずを意味したす。

そうは蚀っおも、 @ DanielRosenwasserのT: * => *の提案は、「先行技術」があるため、ここで最も理にかなっおいるず思いたす。

Haskellでは、挔算子->は実際にはパラメヌタヌ化された型ですおそらくFunc<TArg, TRet>を芖芚化する方が簡単です。 型コンストラクタヌ->は、2぀の任意の型TずUを受け入れ、型T倀をマップする倀コンストラクタヌ぀たり関数の型を生成したす。タむプU 。

興味深いのは、それが芪切なコンストラクタヌでもあるずいうこずです 皮類コンストラクタヌ->は、2぀の任意の皮類T*ずU* 芖芚的な区別のためのアスタリスクを受け入れ、皮類T*型をマップする皮類の型コンストラクタヌを生成したす。 U* 。

この時点でパタヌンに気付くかもしれたせん。 型の定矩ず参照に䜿甚されおいる構文ずセマンティクスは、皮類の定矩ず参照に再利甚されおいるだけです。 実際、それは再利甚さえされおおらず、2぀の異なる宇宙で同時に物事を暗黙的に定矩しおいるだけです。 実際には同型であるずいう事実は、䞍幞な*を陀いお、これが無限のレベル、倀->タむプ->皮類->゜ヌト-> ...で物事を定矩できるこずを意味したすが、それは別の時間のトピック

実際、このパタヌンは非垞に理にかなっおいるため、 ->だけでなく、すべおの型コンストラクタヌに䞀般化する、広く䜿甚されおいるGHCi拡匵機胜を実装する人もいたす。 拡匵機胜は「デヌタの皮類」ず呌ばれ、Haskellが異皮リスト []は倀のリストのタむプであり、タむプのリストの皮類でもある、異皮タプル、「スマヌトレングス」によっおもたらされる方法です。 "ベクトル、および他の倚くの機胜。

おそらく、ただDataKindsたで行きたくないので、芪切なコンストラクタヌ*ず->に固執したすが、Danielの提案した構文に埓う堎合、たたはより䞀般的には、皮類の定矩を型の定矩ず同型にする堎合、この領域での将来の開発を利甚するために自分自身を開きたす。

以前のずりずめのない投皿に続いお、 any代わりに* anyを䜿甚するこずをお勧めしたす。 これは、すべおの倀のタむプずすべおのタむプの皮類の䞡方を衚したす。 構文がわかりにくい堎合は、Haskellの本からペヌゞを取り出し、 'プレフィックスを䜿甚しお皮類ずタむプを明確にするこずができたす。

OPの䟋は次のように蚘述されたす。

interface Monad<(T: 'any => 'any)> {
    // ...
}

Nitpick anyは、2぀の異なるこずを行うずいう意味で、䞀般的に混乱しおいるず思いたす。
これは他のすべおのスヌパヌタむプであり、他のすべおのサブタむプではないため、関数がanyパラメヌタヌを芁求した堎合は、䜕でも入力できたす。 ここたでは順調ですね。
面癜くなるのは、関数が特定の䜕かを芁求し、 anyを提䟛するずきです。 このタむプチェックは、芁求されたものよりも広い他のすべおのタむプが代わりに゚ラヌになりたす。
しかし、ええ、䜕でも。

別の泚意点ずしお、 'は文字列リテラルでも䜿甚されるため、混乱を招きたす。

@Artazorこれに関するニュヌスはありたすか 前回お話ししたように、デフォルトのゞェネリックパラメヌタに基づいおリベヌスする必芁がありたす。 そしお、䜜業䞭のPOCに十分近いのはあなただけだず私には思えたす。

これがサブタむピングずどのように盞互䜜甚するかに぀いおも考える䟡倀がありたす。 *を単独で䜿甚するだけでは䞍十分です。 有界ポリモヌフィズムの代わりにアドホックポリモヌフィズムを䜿甚する蚀語では、受け入れ可胜な型匕数を制限するための制玄の皮類がありたす。 䟋ずしお、 Monad Tの皮類は実際にはConstraintではなく*です。

TypeScriptでは、代わりに構造サブタむプを䜿甚するため、皮類はタむプ間のサブタむプ関係を反映する必芁がありたす。 この䞻題に関するScalaの論文は、芪切なシステムで分散ずサブタむプの関係を衚珟する方法に぀いおいく぀かの良いアむデアを生み出すかもしれたせん「より高い皮類のタむプの平等な暩利に向けお」。

これに぀いお䜕か進展はありたすか

@gcantiによる代替アプロヌチhttps://medium.com/@gcanti/higher-kinded-types-in-typescript-static-and-fantasy-land-d41c361d0dbe

fp-tsが採甚したアプロヌチの問題は、他の方法で蚌明されたラむブラリを再実装するこずです。 私にずっお、typescriptの考え方は、JavaScriptで珟圚ベストプラクティスず考えられおいるものを正しく入力できるようにするこずであり、tsの方法で再実装するこずを匷制するこずではありたせん。

ここには、ファンタゞヌランド、ラムダ、たたは反応フォヌムのいずれかで、珟圚jsラむブラリで䜿甚しおいるコントラクトを正しく蚘述するためにHKTが必芁であるこずを瀺す䟋がたくさんありたす。

これが匷制されおいるのを芋るのは本圓に玠晎らしいでしょう:)

〜この有料で働くこずをいずわない/できる人はいたすか しおお気軜に私に連絡しお議論したす。 たたは、誰かがこれに取り組むために芋぀けるかもしれない誰かを指導するこずができたす、私にも知らせおください。〜 [線集私は[おそらく決定した]https://github.com/keean/zenscript/issues/35#issuecomment -357567767この゚コシステムを攟棄し、このスレッドでのその埌のコメントにより、おそらく倧芏暡な䜜業になるだろうず気づきたした]

@gcantiによる代替アプロヌチhttps://medium.com/@gcanti/higher-kinded-types-in-typescript-static-and-fantasy-land-d41c361d0dbe

結果のmapがただOptionコンテナタむプを明瀺的に指定しおいるので、それを完党に理解する必芁はありたせんでした。したがっお、より高皮類のタむプHKTのように完党にゞェネリックではありたせん。提䟛するこずができる

function map<A, B>(f: (a: A) => B, fa: HKTOption<A>): Option<B> {
  return (fa as Option<A>).map(f)
}

@spionが2016幎8月26日に述べたように、HKTは、ファクトリを必芁ずし、型パラメヌタ化されたコンテナ型自䜓が汎甚である関数を汎甚にするために必芁です。 プログラミング蚀語の蚭蚈に぀いおの議論でこれを

PS興味があれば、この機胜はプログラミング蚀語ランドスケヌプの私の @keeanを含む分析に倧きく圱響したす。

@ shellby3 FWIW Option 's map  Option.ts はむンスタンスを衚し、 Functor ' s map  Functor.ts は、型クラスを衚すため、ゞェネリックです。 次に、任意のファンクタヌむンスタンスで動䜜できる汎甚のlift関数を定矩できたす。

これが匷制されおいるのを芋るのは本圓に玠晎らしいでしょう:)

私は匷く同意したす:)

@ shellby3 このような機胜をマヌゞするには、最善の策は次のようにするこずです。
TSロヌドマップで優先順䜍を付ける。 私は䞻に埗たいく぀かのPRを持っおいたした
小さな修正があった堎合、たたはすでに探しおいた堎合のフィヌドバック/マヌゞ
それらに。 私は吊定的になりたくないが、あなたがそうならそれは考慮事項です
これにリ゜ヌスを投資しようずしおいたす。

2018幎1月8日16:05、「shelby3」 [email protected]は次のように曞いおいたす。

この有料で働くこずをいずわない/できる人はいたすか お気軜にお問い合わせください
私は[email protected]で話し合いたす。 たたは誰でも誰かを指導するこずができたす
これに取り組むこずができるかもしれたせんが、私にも知らせおください。

@gcantiによる代替アプロヌチhttps://github.com/gcanti
https://medium.com/@gcanti/higher -kinded-types-in-
typescript-static-and-fantasy-land-d41c361d0dbe

結果のマップを芳察するので、私はそれを完党に理解するこずを気にしたせんでした
ただオプションコンテナタむプを明瀺的に指定しおいるため、完党ではありたせん
高皮類タむプHKTが提䟛できる䞀般的な方法

関数マップfaA=> B、faHKTOption オプション{ returnfa as Option .mapf }

HKTは、ファクトリずを必芁ずする関数を汎甚化するために必芁です。
タむプパラメヌタ化されたコンテナタむプは、それ自䜓が汎甚である必芁がありたす。 我々は持っおいた
このhttps://github.com/keean/zenscript/issues/10を私たちの
プログラミング蚀語の蚭蚈に぀いおの議論。

PS興味があれば、この機胜は私の
 @keean https://github.com/keean'sを含むの分析
プログラミング蚀語の颚景
https://github.com/keean/zenscript/issues/35#issuecomment-355850515 。 私
私たちの芋解がTypescriptの優先順䜍ず完党に盞関しおいるわけではないこずを理解しおください
Javascript / ECMAScriptずサポヌトのスヌパヌセットになるこずを䞻な目暙ずしおいたす
その゚コシステム。

—
このスレッドにサブスクラむブしおいるため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/Microsoft/TypeScript/issues/1213#issuecomment-355990644 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AC6uxYOZ0a8G86rUjxvDaO5qIWiq55-Fks5tIi7GgaJpZM4C99VY
。

@gcanitiはノむズに぀いおお詫びし、远加の説明をありがずうございたす。 コメントする前にもっず勉匷すべきだった。 もちろん、私はすでに知っおいるファンクタヌはむンスタンスの実装を必芁ずするので、それは抂念化における私の誀りです。

Afaics、あなたの巧劙な「ハック」は、ファクトリを䞀般的に参照するこずを可胜にしたすたずえば、 lift が、ファンクタの特殊なタむプの䞀般的なファクトリの各タむピングを曎新および特殊化するためのモゞュヌル拡匵の远加の定型文が必芁です䟋 Option 。 その定型文は、ゞェネリックファクトリのすべおのゞェネリック䜿甚に必芁ではないでしょうか。たずえば、ゞェネリックsort䟋@keeanず私は話し合いたした。 おそらく、他のコヌナヌケヌスも発芋される可胜性がありたすか

Kotlinはあなたのアむデアをコピヌしたしたか

私は吊定的になりたくありたせんが、これにリ゜ヌスを投資しようずしおいるのであれば、それは考慮事項です。

ええ、その考えは私にも起こりたした。 それを明確にしおくれおありがずう。 @masaeeduが指摘しおいるように、考慮事項の1぀は、型システムぞの䞀般的な圱響ず、型システムが生成する可胜性のあるコヌナヌケヌスであるず思われたす。 これが非垞に培底的に考えられ、実蚌されない限り、おそらく抵抗があるでしょう。

たた、EMCAScriptコンパむルタヌゲットぞの投資のレベルをより正確に確認するために、Ceylonを調べおいるこずに泚意しおください。 もっず勉匷する必芁がありたす。

私もこの制限に噛たれたばかりです。 次の䟋のIを自動的に掚枬したいず思いたす。


interface IdType<T> {
  id: T;
}

interface User {
  id: number;
  name: string;
}

function doStuff<T extends IdType<I>>() {
  const recs = new Map<I, T>();
  return {
    upsert(rec: T) {
      recs.set(rec.id, rec);
    },
    find(id: I) {
      return recs.get(id);
    },
  };
}

(function () {
  const stuff = doStuff<User>();
  stuff.upsert({id: 2, name: "greg"});
  console.log(stuff.find(2));
})();

私の知る限り、これにはより皮類の倚い型が必芁であるか、冗長ず思われる重耇するゞェネリックパラメヌタヌ doStuff<User, number>() を指定する必芁がありたす。

私は最近、この制限にも打たれたした。

私は玄束のために図曞通に取り組んできたした。 それらを操䜜するためのさたざたなナヌティリティ関数を提䟛したす。

ラむブラリの䞭心的な機胜は、ラむブラリ内に眮いたのず同じタむプのpromiseを返すこずです。 したがっお、Bluebird promiseを䜿甚しおいお、関数の1぀を呌び出すず、Bluebirdpromiseずそれらが提䟛するすべおの远加機胜が返されたす。

私は、型システムでこれを゚ンコヌドしたかったが、私はすぐにタむプでの䜜業、これが必芁であるこずを実珟P皮類の* -> *ようにP<T> extends Promise<T> 。

このような関数の䟋を次に瀺したす。

/**
* Returns a promise that waits for `this` to finish for an amount of time depending on the type of `deadline`.
* If `this` does not finish on time, `onTimeout` will be called. The returned promise will then behave like the promise returned by `onTimeout`.
* If `onTimeout` is not provided, the returned promise will reject with an Error.
*
* Note that any code already waiting on `this` to finish will still be waiting. The timeout only affects the returned promise.
* <strong i="14">@param</strong> deadline If a number, the time to wait in milliseconds. If a date, the date to wait for.
* <strong i="15">@param</strong> {() => Promise<*>} onTimeout Called to produce an alternative promise once `this` expires. Can be an async function.
*/
timeout(deadline : number | Date, onTimeout ?: () => PromiseLike<T>) : this;

䞊蚘の状況では、かなりハッキヌなthisタむプを䜿甚するこずで、より高い皮類の必芁性を回避するこずができたした。

ただし、次の堎合は解決できたせん。

/**
* Returns a promise that will await `this` and all the promises in `others` to resolve and yield their results in an array.
* If a promise rejects, the returned promise will rejection with the reason of the first rejection.
* <strong i="21">@param</strong> {Promise<*>} others The other promises that must be resolved with this one.
* <strong i="22">@returns</strong> {Promise<*[]>} The return type is meant to be `Self<T[]>`, where `Self` is the promise type.
*/
and(...others : PromiseLike<T>[]) : ExtendedPromise<T[]>;

this<T[]>か䜕かをするこずを可胜にするハックがないからです。

ドキュメントの私の小さな謝眪に泚意しおください。

䞊蚘の参考文献に瀺されおいるように、この機胜が圹立぀ず私が信じる別のシナリオを手に入れたした私が提案を正しく解釈したず仮定しお。

問題のパッケヌゞでは、ゞェネリック型は通垞ナヌザヌが䜜成するため、型ずしお䜿甚される型なしのゞェネリッククラスたたは関数が必芁です。

私のシナリオに提案を適甚するず、次のようになるず思いたす。

import { Component, FunctionalComponent } from 'preact';

interface IAsyncRouteProps {
    component?: Component<~,~> | FunctionalComponent<~>;
    getComponent?: (
        this: AsyncRoute,
        url: string,
        callback: (component: Component<~,~> | FunctionalComponent<~>) => void,
        props: any
    ) => Promise<any> | void;
    loading?: () => JSX.Element;
}

export default class AsyncRoute extends Component<IAsyncRouteProps, {}> {
    public render(): JSX.Element | null;
}

私の実装ではゞェネリック型を確実に参照する方法がないこずを考えるず、私は䜕かを芋逃しおいるず確信しおいたす。

@ Silic0nS0ldier実際、そのケヌスは今すぐ解決できたす。 次のような構造コンストラクタタむプを䜿甚したす。

type ComponentConstructor = {
    new<A, B>() : Component<A, B>;
}

そしお、 component ?: ComponentConstructorず蚀いたす。

さらに䞀般的には、実際にはゞェネリック関数型を持぀こずができたす。

let f : <T>(x : T) => T

これはランクnパラメヌタヌ倚盞ず呌ばれ、実際には蚀語では非垞にたれな機胜です。 したがっお、TypeScriptに、はるかに䞀般的な機胜である、より皮類の倚い型がない理由に぀いおは、さらに䞍可解です。

ここで説明する制限は、特定のTComponent<T, S>を参照する必芁がある堎合に衚瀺されたす。 しかし、あなたの堎合、これは䞍芁のようです。


typeof Componentを䜿甚しお、コンストラクタヌComponentの型を取埗するこずもできたすが、これにより、サブタむプでさたざたな問題が発生したす。

@GregRos提案された゜リュヌションは有望に芋えたしたが定矩ファむル内の型を受け入れたす、互換性のある型は拒吊されおいたす。 https://gist.github.com/Silic0nS0ldier/3c379367b5e6b1abd76e4a41d1be8217

@ Silic0nS0ldier芁点に぀いおの私のコメントを参照しおください。

@chrisdaviesこれは機胜したすか

interface IdType<T> {
    id: T;
}

interface User {
    id: number;
    name: string;
}

function doStuff<T extends IdType<any>>() {
    type I = T['id']; // <==== Infer I
    const recs = new Map<I, T>();
    return {
        upsert(rec: T) {
            recs.set(rec.id, rec);
        },
        find(id: I) {
            return recs.get(id);
        },
    };
}

(function() {
    const stuff = doStuff<User>();
    stuff.upsert({ id: 2, name: "greg" });
    console.log(stuff.find(2));
})();

@ jack-りィリアムズうん。 それは私のシナリオではうたくいきたす。 私はドキュメントでその䟋を芋぀けおいたせんでした私は物事が欠けおいるこずで知られおいたすが。 ありがずうございたした

私はこの機胜に぀いおよく考えおおり、ある皮の仕様に傟倒しおこの問題に぀いおいく぀か考えおいたすが、それでも倚くの問題を芋るこずができたす。 私の提案は、これたでに提案されたものずは少し異なりたす。


たず第䞀に、型コンストラクタヌにT<*, *>構文を䜿甚するこずは、型コンストラクタヌの耇雑さにうたく察応できないため、悪い考えだず思いたす。 たた、型パラメヌタヌを持぀関数であっおも、関数に察しおこれを行わないため、参照されるたびに型コンストラクタヌの皮類を指定するこずに意味があるかどうかもわかりたせん。

これを実装する最良の方法は、他の型ず同じように通垞の名前でより皮類の倚い型を扱い、制玄を課すために䜿甚できる型コンストラクタヌ自䜓に察しお適切なサブ型関係を定矩するこずだず思いたす。

ある皮の接頭蟞たたは接尟蟞を䜿甚しお、他の型ず区別する必芁があるず思いたす。䞻に、通垞のコヌドを蚘述したいだけの堎合に、型コンストラクタヌに関連する理解できない゚ラヌメッセヌゞからナヌザヌを保護するためです。 ~Type, ^Type, &Typeなどの倖芳が奜きです。

したがっお、たずえば、関数のシグネチャは次のようになりたす。

interface List<T> {
    push(x : T);
}

function mapList<~L extends ~List, A, B>(list : L<A>, f : (x : A) => B) : L<B>;

私は意図的に構築された型に~プレフィックスを䜿甚しおいたせん

ここでextendsを䜿甚するこずにより、基本的に2぀のこずを蚀いたした。

** 1。 必芁な堎合 ~Lは、 ~Listず同じ皮類の型コンストラクタヌです。぀たり、皮類* -> * たたは、 =>なので* => * です。 =>はTypeScriptの矢印です。

  1. ~Lは~Listサブタむプです。**

extendsを䜿甚しお型コンストラクタヌの皮類を瀺すず、 ((* => *) => (* => *)) => *などの任意の耇雑な型コンストラクタヌにスケヌリングされたす。

タむプの識別子でその皮類を実際に芋るこずはできたせんが、私はあなたがそうする必芁はないず思いたす。 型コンストラクタヌ間のサブタむプ関係が型を保持する必芁があるかどうかさえわからないので、1は必芁ないかもしれたせん。

䞍完党な型の構築はありたせん

䞍完党な型の構築をサポヌトすべきではないず思いたす。 ぀たり、次のようなものです。

(*, *) => * => *

それは䟡倀があるよりも倚くの問題を匕き起こすず思いたす。 ぀たり、すべおの型コンストラクタヌは䜕らかの具象型を䜜成する必芁があり、その具象型はTCが定矩されおいるコンテキストで指定する必芁がありたす。

型コンストラクタヌを定矩する構造的な方法

たた、非垞に高次のゞェネリック関数型を含め、他の型を構造的に指定できるのず同じように、型コンストラクタヌを指定する構造的な方法があるべきだず思いたす。 私は次のような構文を考えおきたした

~<A, B> { 
    a : A,
    b : B
}

これは、型パラメヌタヌを持぀関数型の既存の構文に䌌おいたす。

<A, B>() => { a : A, b : B};

この2぀を組み合わせおこれを取埗するこずもできたす。

~<A><B, C> => [A, B, C]

これは、ゞェネリック関数型を構築する型コンストラクタヌです。

利点は、これらの構造型を他の構造型を指定するずき、型制玄を指定するずきなどに䜿甚できるこずです。 これは、他の堎所からは参照できない参照ロヌカルシンボルを䜿甚できるこずを意味する堎合がありたす。

次に䟋を瀺したす。

type List<A, B> = ...;

type AdvancedType<~L extends ~<A>List<A, B>, B> = ...;

䞊蚘の䟋では、構造型コンストラクタヌ~<A>List<A, B>は型パラメヌタヌB参照しおいたす。 少なくずも郚分的に構築されたタむプList<A, *>を゚ンコヌドしない限り、この関係を他の方法で指定するこずはできたせん。 他の䟋もありたす。

サブタむプの関係

サブタむプの関係は理にかなっおいるようですが、それを特城づけるのに倚くの困難に遭遇したした。

私の最初のアむデアは次のずおりでした。 ~Aが~Bサブタむプになる堎合

  1. aそれらは同じ皮類でなければなりたせん制玄ではなく、アリティの芳点から。
  2. b ~Aすべおの正圓なパラメヌタヌ化T₁, T₂, ...に぀いお、 A<T₁, T₂, ...>はB<T₁, T₂, ...>サブタむプでなければなりたせん。

ただし、これにはいく぀かの制限がありたす。

  1. クラスMySpecialPromiseはPromiseLike {}を実装したす

  2. クラスMyArrayPromisePromiseLikeを実装したす

    この堎合も、サブタむプの関係は保存されたせん。

bのより䞀般化されたバヌゞョンは次のずおりです。

b ~Aすべおの正圓なパラメヌタヌ化T₁, T₂, ...に察しお、 A<T₁, T₂, ...>がのサブタむプであるような~Bパラメヌタヌ化S₁, S₂, ...が存圚したす。 B<S₁, S₂, ...> 。

蚀い換えれば、䞊蚘の特性を備えたマッピングF T1、T2、...= S1、S2、...がありたす。 このマッピングは、パラメヌタ構築するために䜿甚する必芁がありたすB<...>パラメヌタ化からA<...> 。 型コンストラクタヌの皮類が異なっおいおも、これを実行できる堎合がありたす。

この関係の問題は、正しいマッピングを芋぀ける方法がわからないこずです。 蚘名的型付けのある蚀語では、次の行に沿ったすべおのステヌトメント

A<...> extends B<...>

~Aの型パラメヌタヌず~Bの型パラメヌタヌの間のマッピングを定矩したす。これにより、マッピングを埩元できたす。 ただし、TypeScriptの構造型付けのシステムでは、この型の明瀺的なステヌトメントに䟝存するこずはできたせん。

1぀の方法は、 implements句や、Scalaに䌌たある皮の抜象型メンバヌなど、適切な型情報を持぀型の型コンストラクタヌのみをサポヌトするこずです。 しかし、これが前進する方法かどうかはわかりたせん。

@ GregRos-興味深いメモ いく぀かの質問。


具䜓的なタむプずはどういう意味ですか 皮類が*䜕か、たたはバむンドされた型パラメヌタヌのない型を意味したすか


䞍完党な型の構築はありたせん
䞍完党な型の構築をサポヌトすべきではないず思いたす。 ぀たり、次のようなものです。
*、*=> * => *

䞍完党な型を䜜成するずはどういう意味ですか L<A>ようなすべおのアプリケヌションは皮類*を持぀必芁があるずいうこずですか。 たずえば、ペアの皮類のコンストラクタヌはあなたの䟋では特別ですか (* => *) => * => *は倧䞈倫ですか


型コンストラクタヌを定矩する構造的な方法

~<A, B> { 
    a : A,
    b : B
}
inferface TyCon<A, B> { 
    a : A,
    b : B
}

これらの䟋は、最初の䟋が匿名であるこずを陀いお、異なりたすか


サブタむプの関係

~Aず~Bは型を参照しおいないので、サブ型の関係を持぀こずは理にかなっおいたすか あるコンストラクタヌが別のコンストラクタヌの「サブタむプ」であるこずを実際に確認する必芁があるのはい぀ですか。 コンストラクタヌが適甚されるたで埅っお、結果の型を確認するこずは可胜ですか

@ jack-williamsフィヌドバックをありがずう

䞍完党な型を䜜成するずはどういう意味ですか L<A>ようなすべおのアプリケヌションに皮類*が必芁だずいうこずですか。 たずえば、ペアの皮類のコンストラクタヌはあなたの䟋では特別ですか (* => *) => * => *は倧䞈倫ですか

はい、正確に。 L<A>ようなすべおのアプリケヌションには、皮類*です。 その䞊でどれだけ売れたかわかりたせん。


これらの䟋は、最初の䟋が匿名であるこずを陀いお、異なりたすか

1぀目は型匏で、2぀目は宣蚀です。 これらのタむプがほずんどの点で同䞀であるのず同じように、それらはほずんどの点で同䞀です。

{
     a : number;
     b : string;
}

interface Blah {
    a : number;
    b : string;
}

構文にはいく぀かの動機がありたす。

  1. TypeScriptの他のすべおず同様に、タむプコンストラクタヌを構造的か぀匿名で指定できたす。
  2. 型匏䞊蚘で型指定された匿名オブゞェクトなどは、関数の型シグネチャなど、宣蚀ステヌトメントを䜿甚できない特定のコンテキストで䜿甚できたす。 これにより、ロヌカルIDを取埗し、他の方法では衚珟できないものを衚珟できたす。

~Aず~Bは型を参照しおいないので、サブ型の関係を持぀こずは理にかなっおいたすか あるコンストラクタヌが別のコンストラクタヌの「サブタむプ」であるこずを実際に確認する必芁があるのはい぀ですか。 コンストラクタヌが適甚されるたで埅っお、結果の型を確認するこずは可胜ですか

型コンストラクタヌは、型ず芋なされる堎合ず芋なされない堎合がありたす。 私はそれらを型ず芋なすこずを提案したす。倀がなく、倀の型を必芁ずするコンテキストに衚瀺できない䞍完党なものです。 これは、このドキュメントでScalaが採甚した哲孊ず同じです。

サブタむプ関係ずは、本質的に、型コンストラクタヌを制玄するために䜿甚できるある皮の「適合」関係を意味したす。 たずえば、 Promise<T> 、 Bluebird<T> 、さたざたなタむプのあらゆる皮類のpromiseで機胜する関数を䜜成する堎合は、TCパラメヌタヌを制玄する機胜が必芁です。䜕らかの方法でPromiseLike<T>をむンタヌフェヌスしたす。

このタむプの関係の自然な蚀葉は、サブタむプの関係です。

䟋を芋おみたしょう。 型コンストラクタヌ間のサブタむプ関係を䜜成したず仮定するず、次のような関数を蚘述できたす。

function mapPromise<~P extends ~PromiseLike, A, B>(promise : P<A>, func : (x : A) => B) : P<B>;

そしお、制玄~P extends ~PromiseLikeは、これがpromiseで機胜し、promiseのみで機胜する関数であるこずを保蚌するこずになっおいたす。 この制玄は、関数の本䜓内で、 promiseがPromiseLike<A>などを実装するこずがわかっおいるこずも保蚌したす。 すべおの埌に、関数の本䜓に掻字䜓によっお認識メンバヌが正確に制玄を通じお存圚するこずが蚌明できるものです。

同様に、 Promise<T> extends PromiseLike<T>は構造的に互換性があり、盞互に眮き換えるこずができるため、 ~Promise extends ~PromiseLike構造的に互換性のある型を構築するため、盞互に眮き換えるこずができたす。


サブタむプの問題の問題を匷調するために、もう䞀床怜蚎しおください。

interface MyPromise<T> extends Promise<T[]> {}

~Promise抜象化するのず同じ方法で、 ~MyPromiseで抜象化できたすか それらの間の関係をどのように捉えたすか

私は以前の話マッピングは、のパラメヌタ䞎えられ、そのマッピングである~MyPromiseのパラメヌタ生成されたす、 ~Promiseによっお構築型のように~MyPromiseのサブタむプでありたす~Promiseによっお構築されたもの。

この堎合、マッピングは次のようになりたす。

T => T[]

@GregRos

この堎合、 ~MySpecialPromiseは皮類が異なるため、 ~PromiseLikeサブタむプではありたせん。

Haskellでは、この皮の問題は、型の郚分適甚を蚱可し、最終的な型パラメヌタヌが実装しおいるむンタヌフェむスの型パラメヌタヌず䞀臎するように型を定矩するこずで解決されたす。

あなたの䟋では、 MySpecialPromiseはMySpecialPromise<TSpecial, TPromiseVal>ずしお定矩され、 ~MySpecialPromise<SpecialType>は~Promiseず同じ皮類になりたす。

@GregRos

サブタむプ関係ずは、本質的に、型コンストラクタヌを制玄するために䜿甚できるある皮の「適合」関係を意味したす。 たずえば、Promiseのように、さたざたなタむプのあらゆる皮類のPromiseで機胜する関数を蚘述したい堎合、 青い鳥など、むンタヌフェむスPromiseLikeを䜿甚しおTCパラメヌタを制玄する機胜が必芁です。䜕らかの方法で。
function mapPromise<~P extends ~PromiseLike, A, B>(promise : P<A>, func : (x : A) => B) : P<B> ;

その関数の型チェックに関しおは、遞択したTに察しおBlueBird<T>ずPromiseLike<T>を統合しようずするず思いたすが、これらは単なる具䜓的な型であり、サブタむプに分類されたす。 コンストラクタヌ~BlueBirdず~PromiseLike特別な関係が必芁な理由がわかりたせん。

こんな感じで䜿われるず思いたすか


let x: <P extends ~PromiseLike>(input : P<A>, func : (x : A) => B) : P<B>;
let y: <P extends ~BlueBird>(input : P<A>, func : (x : A) => B) : P<B>;
x = y;

ここで、yの制玄がxの制玄を意味するこずを確認したい堎合がありたすが、TypeScriptには、 BlueBird<T>が䜿甚可胜なPromiseLike<T>を拡匵するこずを確認する機構がただありたせんか

@ jack-williams次の制玄をどのように指定するかによっお決たりたす。

〜Pは、すべおのA 、 P<A>がPromiseLike<A>サブタむプであるような型コンストラクタヌです。

どのような構文を䜿甚したすか どんなコンセプトを䜿いたすか あなたはこのようなものを曞くこずができたす

function mapPromise<~P, A, B where P<A> extends PromiseLike<A>>

ただし、この構文には制限がありたす。 たずえば、このクラスを制玄するために宣蚀された時点でタむプP<A>を構築できないため、このクラスをたったく衚珟できたせん。

class PromiseCreator<~P extends ~PromiseLike> {
    create<A>() : P<A>;
}

しかし、次のように、そのために実存型を䜿甚できるず思いたす。

//Here A is not a captured type parameter
//It's an existential type we introduce to constrain ~P
class PromiseCreator<~P with some A where P<A> extends PromiseLike<A>> {
    create<A>() : P<A>;
}

次に、オプションで存圚型を䜿甚しお、関数たたは型のシグネチャ内で構築された型を介しおすべおの型コンストラクタヌを制玄するように芁求できたす。

実存型の堎合、これはマッピングずのサブタむプ関係ず同じ衚珟力を持ちたす。

ただし、これには耇数の問題がありたす。

  1. ((* => *) => *) => *などの皮類で型コンストラクタヌを指定するには、倚くの実存型を導入する必芁があり、そのうちのいく぀かは高階でなければなりたせん。 それらのすべおは、関数たたはクラスのシグニチャに出珟する必芁がありたす。
  2. マッピングを芋぀けるよりも、問題の存圚タむプを芋぀ける方が簡単かどうかは完党にはわかりたせん。
  3. サブタむプの関係よりも゚レガントではないず思いたす。
  4. 察凊しなければならない別の圢匏のタむプを導入する可胜性がありたす。

@GregRos

どのような構文を䜿甚したすか どんなコンセプトを䜿いたすか

_個人的に_私は特別な構文を䜿甚せず、次を䜿甚したす。

function mapPromise<P extends PromiseLike, A, B>(p: P<A>, f: (x: A) => B): P<B>

class PromiseCreator<P extends PromiseLike> {
    create<A>() : P<A>;
}

しかし、これはnumberようなものをnull-aryコンストラクタヌず芋なしおいるので、私の意芋です。したがっお、区別する必芁はありたせん。

コンストラクタヌ関数のサブタむプに関する私の芋解は、可胜な限り単玔に保぀こずです。 それらは同じアリティを持ち、パラメヌタは、Scalaの論文のように、反倉性ず共分散を考慮に入れお、互いにサブカむンドである必芁がありたす。

郚分適甚は、それらが異なるアリティを持っおいる堎合を回避するこずができたす型コンストラクタヌの自動カリヌ化は気にしないので、 MySpecialPromise<SpecialType>曞くだけです。

interface MyPromise<T> extends Promise<T[]> {}の䟋では、正盎に蚀うず、このケヌスを凊理するのに耇雑さの䟡倀があるずは確信しおいたせん。これがなくおも十分に圹立぀機胜だず思いたす。

その堎合の凊理​​は私が思うに次のように蚀うのず同じです ~MyPromise extends ~(Promise . [])ここで、 []はリストコンストラクタヌで、 .はコンストラクタヌ構成です。 コンストラクタヌの構造を調べるだけでは䞍十分なため、状況はさらに難しくなっおいるようですが、構成に぀いおも掚論する必芁がありたす。

@ jack-williamsこれはデフォルトの型パラメヌタでは機胜したせん。 P extends Fooず曞くず、 Fooにはデフォルトの型パラメヌタヌ、぀たりtype Foo<T = {}> = ...がありたすが、 P皮類は䜕ですか

私は高次の型を承認しおいるず蚀いたいだけです実際のTypeScriptプロゞェクトでは、それらが圹立぀状況がありたした。

しかし、カリヌ化をサポヌトするべきではないず思いたす。 私はHaskellが倧奜きですが、それはTypeScriptには適合したせん。

高次の型は、カリヌ化や郚分適甚がなくおも䟿利ですが、郚分適甚が必芁な

Foo<number, _>  // equivalent to `type Foo1<A> = Foo<number, A>`

@ cameron-martin

線集申し蚳ありたせんが、私のコメントはあたり明確ではなかったず思いたす。 Pは独自の皮類がありたす。぀たり、䜿甚によっお皮類が課せられたす。 Say制玄は垞に最高の皮類であるず想定されるため、 Fooは~Fooず想定されたす。 Pを匷制的に䞋䜍の皮類にする堎合にのみ、 Fooにデフォルトパラメヌタがあるかどうかを確認したす。 これに関する私の懞念は芪切な掚論ですが、その堎合、 ~圹に立たず、完党な泚釈が必芁だず思いたす。

Pは独自の皮類がありたすね 質問は、私たちが治療を行うこずはないでしょうFooのように~Foo 、たたはずしおFoo<{}> 私はそれはP.だから、䞀皮のによっお駆動される䞻匵するだろうもしPはデフォルトのパラメヌタヌを匷制する型であり、 Pがコンストラクタヌ* => *堎合、 Fooも同じように扱いたす。

@Pauanあなたの提案に同意したす。

@ jack-williams先に述べたように、サブタむプの抂念を怜蚎したした。

私の最初のアむデアは次のずおりでした。 ~Aが~Bサブタむプになる堎合

  1. aそれらは同じ皮類でなければなりたせん制玄ではなく、アリティの芳点から。
  2. b ~Aすべおの正圓なパラメヌタヌ化T₁, T₂, ...に぀いお、 A<T₁, T₂, ...>はB<T₁, T₂, ...>サブタむプでなければなりたせん。

問題は、物事をできるだけ単玔に保぀ず、逆説的で蚀語に適合しないサブタむプ関係になっおしたうこずです。

もしMyPromise<T> extends Promise<T[]>手段はMyPromise<T>䜿甚可胜でなければならどこでもPromise<T[]>䜿甚可胜ではありたせんが、これはもはやケヌスだろう。

asを䜿甚しおa : MyPromise<T>をPromise<T[]> asに倉換した堎合、アップキャストになりたすが、逆説的にa割り圓おが容易になりたす。

既存のサブタむプの関係に埓う既存の䞀般的な制玄を䜿甚しお、同様の効果を達成し、奇劙な動䜜を匕き起こすこずもできたす。

function id1<A, ~P extends ~PromiseLike>(p : P<A>) : P<A>;

function id2<A, P extends Promise<A[]>>(p : P) : P {
    //ERROR - P does not extend PromiseLike<A>
    return id1(p);
}

タむピングは、副䜜甚ずしおも少なくずも郚分的には名目䞊のものになりたす。 これらのタむプは突然異なり、珟圚は同じです。

type GenericNumber<T> = number;

type RegularNumber = number;

型パラメヌタヌを持぀耇雑な結合/亀差型、玔粋な構造型、メンバヌ内包衚蚘を持぀型などにどのような圱響があるのか​​さえわかりたせん。

私の個人的な感想は次のずおりです。型コンストラクタヌに察するサブタむプの関係は、既存のものに反察するのではなく、尊重する必芁がありたす。 悲しいこずに、これにはもっず耇雑なものが必芁です。


型コンストラクタヌにある皮の特別な衚蚘法を䜿甚する最倧の理由は、99の開発者が型コンストラクタヌが䜕であるかを知らず、それらに関する゚ラヌメッセヌゞで攻撃されたくないずいうこずです。

これは、すべおの開発者が圏論の䞊玚コヌスを受講するこずを法埋で矩務付けられおいるHaskellずは倧きく異なりたす。

二次的な理由は、堎合によっおは前述のデフォルトのパラメヌタヌの堎合のように、構文があいたいになるか、特定の型コンストラクタヌをたったく抜象化できないこずです。

線集申し蚳ありたせんが@GregRos私はあなたの埌者のコメントを芋たせん

型コンストラクタヌに察するサブタむプの関係は、既存のものに反察するのではなく、尊重する必芁がありたす。

これが達成できれば、私は同意したす。 私はすべおの詳现ずこれがどれほど簡単であるかに぀いお頭を悩たせおいたせん。

二次的な理由は、堎合によっおは前述のデフォルトのパラメヌタヌの堎合のように、構文があいたいになるか、特定の型コンストラクタヌをたったく抜象化できないこずです。

制玄を䜎くする必芁があるたで、垞に最高の皮類の制玄を想定するず、あいたいになるこずに同意するかどうかはわかりたせん。 これはアサヌションではなく、他の䟋を瀺しおいる堎合は十分に公平です。


問題は、物事をできるだけ単玔に保぀ず、逆説的で蚀語に適合しないサブタむプ関係になっおしたうこずです。

それは本圓かもしれたせん、私は代替案が実際に実装できるかどうかだけが心配だず思いたす。 より耇雑な゜リュヌションが機胜すれば、それは玠晎らしいこずです。

マッピング関数の存圚を瀺すサブタむプのより䞀般的な抂念を持぀こずは、䞀般的に実装するのが難しいようです。 次の䟋はルヌルを正しく解釈しおいたすか

b〜Aのすべおの正圓なパラメヌタ化T1、T2、...に察しお、Aが次のような〜Bのパラメヌタ化S1、S2、...が存圚したす

FA、B=number、Bのマッピングが䞎えられた堎合、次の堎合、XはYのサブタむプになりたす。

type X = ~<A,B> = {x : B};
type Y = ~<A,B> = A extends number ? {x: B} : never;

ただし、 X<string,number>はY<string,number>サブタむプにはなりたせん。

マッピングの_存圚_が十分であるかどうかはわかりたせん。 〜Aず〜Bを関数ずし、〜Bが〜Aに近䌌するこず、たたは〜Aが〜Bのサブタむプであるこずを瀺したい堎合、〜Aがaであるような関数〜Cがあるこずを瀺したす。 〜B。〜Cのサブタむプでは䞍十分だず思いたすCはマッパヌです。 私は_all_マッピングの堎合でなければなりたせん。

function id1<A, ~P extends ~PromiseLike>(p : P<A>) : P<A>;

function id2<A, P extends Promise<A[]>>(p : P) : P {
    //ERROR - P does not extend PromiseLike<A>
    return id1(p);
}

私はこの䟋に完党には埓いたせん、ここで゚ラヌが発生しないようにする必芁がありたすか これらを読んだずころ、 id1は、すべおの_inputs_にPromiseLikeを䞎える関数Pによっお構築された入力が必芁であるずいうこずです。 id2は、PromiseをA []に適甚するサブタむプでなければならない倀に぀いお話しおいるのに察しお。 id2タむプから、 id1に必芁な情報を埩元できるかどうかはわかりたせん。 私はあなたの䞻匵を誀解しおいるかもしれないず思いたす。

これらのタむプは突然異なり、珟圚は同じです

繰り返しになりたすが、私はあなたの䞻匵を芋逃しおいるかもしれたせんが、それらがどのように同じであるかはわかりたせん。 型内でRegularNumberをGenericNumberに眮き換えるこずはできたせん。埌者に匕数を指定する必芁がありたす。

マッピングの存圚で十分かどうかはわかりたせん。 〜Aず〜Bを関数ずし、〜Bが〜Aに近䌌するこず、たたは〜Aが〜Bのサブタむプであるこずを瀺したい堎合、〜Aがaであるような関数〜Cがあるこずを瀺したす。 〜B。〜Cのサブタむプでは䞍十分だず思いたすCはマッパヌです。 私はすべおのマッピングに圓おはたる必芁がありたす。

ええ、あなたは正しいです、そしおあなたが提䟛した反䟋もそうです。 私は他の反䟋を芋぀けたした。 たったく機胜したせん。

このスレッドずたくさんの返信を読み盎したした。 私はあなたが倚くの点で正しいず思いたす、そしお私は間違った方法で問題を芋おきたした。 私が蚀いたいこずを説明したす。

制玄を䜎くする必芁があるたで、垞に最高の皮類の制玄を想定するず、あいたいになるこずに同意するかどうかはわかりたせん。 これはアサヌションではなく、他の䟋を瀺しおいる堎合は十分に公平です。

あいたいであるか、参照できなくなっおいたす。 䞊蚘の䟋のように、 Fooの型コンストラクタヌは、型自䜓によっお隠されおいるため、参照できなくなりたす。 ~Fooを曞いたり、 Foo<*>や~<A>Foo<A>など、他のものず競合しないものを曞いたりすれば、この皮の問題は発生したせん。

はい、゚むリアスを定矩するこずでそれを回避できたすが、あたりきれいではありたせん。

type Foo2<T> = Foo<T>

私が蚀ったように、これが最も重芁な懞念事項ではないず思いたす。

私はこの䟋に完党には埓いたせん、ここで゚ラヌが発生しないようにする必芁がありたすか 私がこれらを読んだのは、id1には、すべおの入力に察しおPromiseLikeを䞎える関数Pによっお構築された入力が必芁であるずいうこずです。 id2は、PromiseをA []に適甚するサブタむプでなければならない倀に぀いお話しおいるのに察しお。 id2のタむプからid1に必芁な情報を回埩できるかどうかはわかりたせん。 私はあなたの䞻匵を誀解しおいるかもしれないず思いたす。

それは正しい読み方です、ええ。 ただし、 P extends Promise<A[]>堎合は、 id1など、 Promise<A[]>を受け入れる任意の堎所に割り圓おるこずができたす。 これが珟圚の状況であり、サブタむピングの意味です。

もう避けられないず思いたす。

繰り返しになりたすが、私はあなたの䞻匵を芋逃しおいるかもしれたせんが、それらがどのように同じであるかはわかりたせん。 型内でRegularNumberをGenericNumberに眮き換えるこずはできたせん。埌者に匕数を指定する必芁がありたす。

私が意味したのはこれですすべおのTのタむプGenericNumber<T>ず、タむプRegularNumberは同䞀で亀換可胜です。 䞀方がチェックを入力し、もう䞀方が入力しないコンテキストはありたせん。 少なくずも今は。

私たちが話しおいるこずはそれらを違うものにするでしょう。 GenericNumber<T>はTCからのものであるため、 RegularNumberができない堎所で

私はこれに぀いお考えたした、そしおそれは避けられないかもしれなくお、必ずしも悪いわけではないず思いたす。 ただ新しい、異なる振る舞い。

それに぀いお考える1぀の方法は、typeパラメヌタヌがtypeの「構造」の䞀郚になるずいうこずです。

TCはもっず異なる行動に぀ながるず思いたす。

新しい方向性

たず第䞀に、正しいサブタむプの関係はマッピングを持たない関係であるずいう点であなたは正しいず思いたす。

私の最初のアむデアは次のずおりでした。 ~Aが~Bサブタむプになる堎合

  1. aそれらは同じ皮類でなければなりたせん制玄ではなく、アリティの芳点から。
  2. b ~Aすべおの正圓なパラメヌタヌ化T₁, T₂, ...に぀いお、 A<T₁, T₂, ...>はB<T₁, T₂, ...>サブタむプでなければなりたせん。

マッピングのこず...正盎なずころ、それはかなり愚かです。 MyPromise<T> extends Promise<T[]>ず~Promiseを統合する方法はもうないず思いたす。 誰かが他のこずを考えおいるかどうか知りたいです。

たた、このルヌルでも機胜しない䟋がないかどうかも知りたいです。

型コンストラクタヌの制玄がサブタむプの関係を䜿甚しお衚珟されるこずに同意する堎合、これは非垞にうたく機胜しおいるように芋えたすが、他のこずに移るこずができたす。

構文に぀いお

私たちはこの問題に぀いお実際には同意しおいないようです。 ~Promise䌌たプレフィックス構文を匷く奜みたす。 抂念的には、 ~は、「のTCぞの参照」挔算子などず芋なすこずができたす。

私はそれが代替案よりも優れおいるいく぀かの理由を挙げたず思いたす

  1. 完党に明癜です。

    1. この構文に関連する゚ラヌも明確です。 誰かが型をパラメヌタ化するのを忘れた堎合、それらが䜕であるかを知らなくおも、型コンストラクタに関する゚ラヌは発生したせん。

    2. 副䜜甚ずしお、既存の゚ラヌテキストずロゞックを倉曎する必芁はありたせん。 誰かがPromise曞き蟌んだ堎合、゚ラヌメッセヌゞは珟圚ずたったく同じになりたす。 TCに぀いお話すために倉曎する必芁はありたせん。

  2. 構造構文にも拡匵できたす。
  3. 解析しやすいず思いたす。 タむプが予期される堎所に衚瀺される~\wは、TCぞの参照を瀺しおいるず芋なされたす。
  4. 入力が簡単です。

他の方にもご意芋をいただければ幞いです。

和集合、共通郚分、およびデフォルトの型パラメヌタヌに぀いお

* & (* => *) 、 * | (* => *)などのフォヌムのオヌバヌロヌド/混合の皮類は合法ですか それらには興味深い甚途がありたすか

それらは悪い考えであり、掚論するのは難しいず思いたす。 たた、 * | (* => *)を明確にしお、そこから型を䜜成できるようにするために必芁な型泚釈の皮類もわかりたせん。

このような皮類が珟圚存圚しおいるず蚀える1぀の方法は、デフォルトの型パラメヌタヌを持぀型です。

type Example<A = number> = {}

この型は、型パラメヌタを受け入れお型を構築できるため、皮類* & (* => *)あるず蚀えたすが、必ずしもそうする必芁はありたせん。

デフォルトの型パラメヌタヌは、型を説明する方法ではなく、省略圢である必芁があるず思いたす。 したがっお、タむプの皮類を決定するずきは、デフォルトのタむプパラメヌタを無芖する必芁があるず思いたす。

ただし、 ~Promise | ~Arrayなどのタむプに぀いお話すこずは理にかなっおいる堎合がありたす。 それらは同じ皮類なので、互換性はありたせん。 これはサポヌトされる

察凊しなければならないこず

次のような関連する状況に察凊する必芁がありたす。

type Example = (<~P extends ~Promise>() => P<number>) | (<~M extends ~Map>() => Map<string, number>);

しかし、これは実際には皮類(* => *) | (*, *) => *含みたせんが、䜕か別のものです

他のTCを構築しおいたすか

前に述べたように、 * => (* => *)ような他のTCを構築するTCを甚意するのは良い考えではないず思いたす。 これらはカリヌ化などをサポヌトする蚀語では暙準ですが、TypeScriptでは暙準ではありたせん。

~構文ずサブタむプの関係を䜿甚しおそのような型を定矩するこずを私が芋るこずができる方法はたったくないので、それらを犁止するための特別な芏則は必芁ありたせん。 それらを機胜させるには特別なルヌルが必芁になりたす。

おそらく、次のように構造的に定矩できるず思いたす。

~<A>~<B>{a : A, b : B}

それが私が考える唯䞀の方法です。

䞊䜍の機胜ずの盞互䜜甚

型パラメヌタヌを受け取る関数型ずの自然ではあるが耇雑な盞互䜜甚がありたす。

type Example<T> = <~P extends ~Promise>(p : P<T>) : P<T>;

この盞互䜜甚を䜕らかの方法で停止する必芁がありたすか このようなタむプは非垞に耇雑になっおいるこずがわかりたす。

䞀般的に、TCパラメヌタを衚瀺しおはいけない堎所はありたすか

私の構造構文は良い考えですか

すぐに実装する必芁はないず思いたすが、それでも私の構造構文は良い考えだず思いたす。 それはあなたを可胜にしたす

  1. 制玄では、他のタむプパラメヌタず同様にロヌカル識別子を䜿甚したす。
  2. ~<A>Map<string, A> 、 ~<A, B>Map<B, A>などの非垞に明瀺的で柔軟な方法で、型コンストラクタヌを郚分的に適甚したす。
  3. 型の他のすべおの偎面には構造構文があるため、TCにもそのような構文が必芁です。

ずは蚀うものの、TCはこれがなくおも完党に機胜する可胜性があり、最初のPRではおそらくTCが関䞎したせん。

条件付きタむプずの盞互䜜甚

機胜は条件付きタむプでどのように機胜したすか あなたはこれを行うこずができるべきですか

type Example<~P extends ~PromiseLike> = ~P extends ~Promise ? 0 : 1

自分自身は完党にはわかりたせん。 条件付き型はただ完党に消化されおいたせん。

過負荷の解決

これはやりづらい気がしたす。 さたざたな圢匏の過負荷解決によっおさたざたなタむプが䜜成されるため、これは実際には非垞に重芁です。

ずはいえ、今のずころ良い䟋は思い぀かない。

明確に定矩された䞭間蚀語を䜿甚しおTypeScriptを開始点ずしお蚘述した堎合、これの倚くは重芁なポむントでした。 䟋システムF <たたはSimplified DependentMLなどのサりンド䟝存型システムの1぀。

これが前に解決されたら正盎驚かされる
https://github.com/Microsoft/TypeScript/issues/14833

17961はおそらくこれを間接的に解決できるず思いたす。 詳现に぀いおは、この芁点を参照しおください。

BifunctorずProfunctor型は、制玄レベルでは少し耇雑であるこずに泚意しおください。 infer Tではなく、明らかにナニバヌサル型を䜿甚する方がはるかに簡単です。 thisを「戻り倀の型」玔粋に型レベルずしお䜿甚できれば、ほずんどのむンタヌフェむスの定矩が簡単になりたす。

私はTSのヘビヌナヌザヌではないので、間違いを犯した可胜性がありたす。 @ tycho01それを芋お、タむプの混乱のどこかで倱敗したかどうかを確認しおください。私が尋ねる理由は、あなたが埌ろにいるからです。䞊蚘のPR、そしお私はあなたの他の実隓やナヌティリティのいく぀かを芋おきたした。

@isiahmeadows @ tycho01うわヌ...

あなたが正しい。 私がそれを正しく理解すれば、それはほずんど同じ結果をもたらしたす。

いく぀かの違いがありたす。 しかし、機胜的にはほずんど同じであり、これらの違いは解決できるず思いたす。

正しい型関数を掚枬するこずはできたせん

function example<~P extends ~PromiseLike>(p : P<number>) : P<string>;

ここで、 ~Bluebirdからp ~Promiseず~Bluebirdを掚枬できたす。 ただし、次のようにするず、次のようになりたす。

function example<F extends <T>(t: T) => PromiseLike<T>>(p : F(number)) : F(string)

私はこれがうたくいくかどうか非垞に疑っおいたす

example(null as Promise<number>)

Fが次のように意図されおいるず掚枬する方法はありたせん。

<T>(t : T) => Promise<T>

この機胜は特別なものずは芋なされないためです。 䞀方、TCの堎合、䞀郚の型には基本的に「暗黙の」型レベルの機胜がありたす。それはTCです。

既存のTCを簡単に参照するこずはできたせん

私の提案のように~Promise行うこずはできたせん。 構造圢匏を䜿甚しお、型を盎接゚ンコヌドする必芁がありたす。

type PromiseTC = <T>() => Promise<T>

確かに、それは懞念事項です。 これは、既知の匕数型から汎甚関数自䜓を掚論する機胜が必芁な型掚論の問題です通垞発生するのずは逆です。 ほずんどの堎合に機胜するのに十分䞀般的な方法で解決できたすが、重芁な新しい特殊なケヌスが必芁です。

NoInfer<T>を戊略的に䜿甚するこずで郚分的に解決できるかもしれたせんが、それをどのように行う必芁があるのか​​、そしお䞀般的なケヌスでさえどれだけ察凊できるのか、100確信はありたせん。

@GregRos

私は構文を匷く支持しおいたせん。それは私の奜みであり、 ~には倚くのメリットがありたす。 掚論が垞に可胜であるずは限らないため、考慮すべき䞻なこずは、明瀺的な皮類の泚釈の構文が必芁かどうかだず思いたす。


マッピングのこず...正盎なずころ、それはかなり愚かです。 MyPromiseを統合する方法はないず思いたすPromiseを拡匵したす

マッピングのこずはただ有甚な抂念だず思いたすが、䞊蚘の堎合、 ~MyPromiseを~Promiseず統合しようずするべきではないず思いたす。統合する必芁があるものです。は~MyPromiseず~<T>Promise<T[]>であり、 ~(Promise . [])曞くこずもできたす。 欠けおいたのは、マッピングがサブタむプ関係の䞀郚である必芁があるずいうこずだず思いたす。それはPromiseず同じくらいコンストラクタヌの䞀郚です。 この䟋では、マッピングは単なるリストコンストラクタヌです。

interface A<T> {
    x: T;
} 

interface B<T> {
    x: T[];
}

~<T>B<T>は~<T>A<T[]>拡匵したすか はい。 ~<T>B<T>は~<T>A<T>拡匵したすか いいえ。しかし、最終的には2぀の無関係な質問です。

型コンストラクタヌの制玄がサブタむプの関係を䜿甚しお衚珟されるこずに同意する堎合、これは非垞にうたく機胜しおいるように芋えたすが、他のこずに移るこずができたす。

はい、それは物事を説明する良い方法のように思えたす。


正しい型関数を掚枬するこずはできたせん

function example<~P extends ~PromiseLike>(p : P<number>) : P<string>;
ここでは、pから~Promiseず~Bluebirdを掚枬できたす。

これはアサヌションではなく、型チェックがどのように機胜するか完党にはわからないため、よりオヌプンな質問です。 䞊蚘のむンタヌフェヌスA䟋ずしお䜿甚するず、タむプA<number>ず{x: number}は区別できないため、コンストラクタヌを掚枬できるかどうかはわかりたせん。コンストラクタヌのアプリケヌションから返された型から。 P<number>からPを回埩するこずは可胜でしょうか これをサポヌトするために物事が倉曎される可胜性があるず確信しおいたす、私はそれが今䜕をしおいるのか疑問に思っおいたす。

17961からのクロスレスポンスですが、残念ながら@isiahmeadowsのアプロヌチを機胜させる方法が

したがっお、入力Promise<number>たたはBluebird<number>に基づいお、これらのタむプの未適甚バヌゞョンを掚枬しお、たずえばstring再適甚できるようにしたいようです。 でもそれは難しいですね。

入力型が構造的に同等のものではなくこのようなものであっおも構造的に型付けされた蚀語ですよね、たずえばBluebirdに2぀のパラメヌタ型がある堎合、この掚論も曖昧になりたす。その時点で<string>型のparamアプリケヌションはもはや意味をなさないかもしれたせん。
私はそこに良い解決策がわかりたせん。 免責事項ここでの議論は少し遅れおいたす。

@ tycho01人々がT明瀺的にむンスタンス化した堎合、これらの問題はすべお解消されたすか

ずにかくすべおの堎合に掚論を解決できるずは思えないので、それは合理的だず思いたす。

@ jack-williamsこれたでのずころ17961ではありたせんが、ディスパッチに䜿甚するず圹立぀ず思いたす。

let arr = [1, 2, 3];
let inc = (n: number) => n + 1;
let c = arr.map(inc); // number[]
let map = <Functor extends { map: Function }, Fn extends Function>(x: Functor, f: Fn) => x['map'](f); // any on 2.7 :(
let e = map(arr, inc);

@ tycho01はい、メ゜ッド呌び出しでTがむンスタンス化されおいないため、私の提案がひどいこずに気づきたした。

次のようなものは動䜜したすか

interface TyCon<A> {
    C: <A>(x: A) => TyCon<A>
}

interface Functor<A> extends TyCon<A> {
    C: <A>(x: A) => Functor<A>;
    fmap<B>(this: this["C"](A), f: (x: A) => B): this["C"](B);
}

interface Option<A> extends Functor<A> {
    C: <A>(x: A) => Option<A>;
}

@ jack-williams問題は、動䜜がfp-tsのADT実装ずどのように比范されるかずいうこずだず思いたすが、これはうたくいくようです。 おそらくTyConもありたせん。

@ jack-williams @isiahmeadows 

すでに$Call利甚可胜であるため、tryflowでアむデアを詊したした。 私にずっおはどういうわけか反応しなくなったようですが...

interface Functor<A> {
    C: <A>(x: A) => Functor<A>;
    fmap<B>(f: (x: A) => B): $Call<$ElementType<this, "C">, B>;
}
// this: $Call<$ElementType<this, "C">, A>, 
// ^ flow doesn't seem to do `this` params

interface Option<A> extends Functor<A> {
    C: <A>(x: A) => Option<A>;
}

let o: Option<string>;
let f: (s: string) => number;
let b = o.fmap(f);

@ tycho01 thisフロヌから$ElementTypeプロパティを取埗するこずはできないず思いたす

@ tycho01実際にはこれをtypescriptでも機胜させるこずはできたせん
遊び堎 https 

@goodmind FunctorからMaybe fmapをコピヌした埌、 Functor<number> Maybe<number>ではなく
型呌び出しを䜿甚するず、型の実行時実装が必芁になるのではなく、型だけが存圚するように改善されるず思いたす。
さお、ファンクタヌはすでに独自のfmap実装を必芁ずしたす。 しかし、それは掟生メ゜ッドにずっおは最悪です。
振り出しに戻っお。 /

https://github.com/SimonMeskens/TypeProps/issues/1でいく぀かの関連するアむデア

アルファ版をできるだけ早くリリヌスする予定ですが、その号の䟋を曞いおいる私ず䞀緒にフォロヌしお、すでにその感觊を぀かむこずができたす。

この特定の問題を完党に解決するには少し時間がかかりたすが、私が探しおいるのは単玔な内容ですが、パラメヌタヌ化された汎甚型がないために入力できないコヌドの実際の䟋です。 私はそれらのほずんどを入力できるず思いたす抜象リフト型コンストラクタヌに䟝存しない堎合。 䞊蚘のリポゞトリでコヌドを䜿甚しお問題を自由に開いおください。可胜であれば、入力したすたたは、ここに投皿するこずもできたす。

ヘッズアップ私は23809でこれを実装する詊みを始めたした。 ただ非垞に䞍完党ですが、興味があればチェックしおください。

私はあなたたちに簡単な䟋を玄束したした、ここにありたす。 これは、ラむブラリの䜜成から孊んだいく぀かのトリックを䜿甚しおいたす。

type unknown = {} | null | undefined;

// Functor
interface StaticFunctor<G> {
    map<F extends Generic<G>, U>(
        transform: (a: Parameters<F>[0]) => U,
        mappable: F
    ): Generic<F, [U]>;
}

// Examples
const arrayFunctor: StaticFunctor<any[]> = {
    map: <A, B>(fn: (a: A) => B, fa: A[]): B[] => {
        return fa.map(fn);
    }
};
const objectFunctor: StaticFunctor<object> = {
    map: <A, B>(fn: (a: A) => B, fa: A): B => {
        return fn(fa);
    }
};
const nullableFunctor: StaticFunctor<object | null | undefined> = {
    map: <A, B>(
        fn: (a: A) => B,
        fa: A | null | undefined
    ): B | null | undefined => {
        return fa != undefined ? fn(fa) : fa;
    }
};

const doubler = (x: number) => x * 2;

const xs = arrayFunctor.map(doubler, [4, 2]); // xs: number[]
const x = objectFunctor.map(doubler, 42); // x: number
const xNull = nullableFunctor.map(doubler, null); // xNull: null
const xSome = nullableFunctor.map(doubler, 4 as number | undefined); // xSome: number | undefined

const functor: StaticFunctor<unknown | any[]> = {
    map(fn, fa) {
        return Array.isArray(fa)
            ? arrayFunctor.map(fn, fa)
            : fa != undefined
                ? objectFunctor.map(fn, fa)
                : nullableFunctor.map(fn, fa);
    }
};

const ys = functor.map(doubler, [4, 2]); // ys: number[]
const y = functor.map(doubler, 42); // y: number
const yNull = functor.map(doubler, null); // yNull: null
const ySome = functor.map(doubler, 42 as number | undefined); // ySome: number | undefined

// Plumbing
interface TypeProps<T = {}, Params extends ArrayLike<any> = never> {
    array: {
        infer: T extends Array<infer A> ? [A] : never;
        construct: Params[0][];
    };
    null: {
        infer: null extends T ? [never] : never;
        construct: null;
    };
    undefined: {
        infer: undefined extends T ? [never] : never;
        construct: undefined;
    };
    unfound: {
        infer: [NonNullable<T>];
        construct: Params[0];
    };
}

type Match<T> = T extends infer U
    ? ({} extends U ? any
        : TypeProps<U>[Exclude<keyof TypeProps, "unfound">]["infer"]) extends never
    ? "unfound"
    : {
        [Key in Exclude<keyof TypeProps, "unfound">]:
        TypeProps<T>[Key]["infer"] extends never
        ? never : Key
    }[Exclude<keyof TypeProps, "unfound">] : never;


type Parameters<T> = TypeProps<T>[Match<T>]["infer"];

type Generic<
    T,
    Params extends ArrayLike<any> = ArrayLike<any>,
    > = TypeProps<T, Params>[Match<T>]["construct"];

サンプルを曎新しお簡略化したした。ここにも遊び堎のリンクがありたす。
遊び堎

䞊蚘のNPMラむブラリを远加したので、簡単に操䜜できたす。 私が適切なテストを受けるたで珟圚アルファ版ですが、HKTを曞き蟌もうずしおいる皆さんの助けになるはずです。

Githubリンク

私は、条件付き型を䜿甚しお飜和型内の仮想型倉数を眮き換えるこずにより、HKTをシミュレヌトする簡単なアプロヌチで遊んでいたす。

declare const index: unique symbol;

// A type for representing type variables
type _<N extends number = 0> = { [index]: N };

// Type application (substitutes type variables with types)
type $<T, S, N extends number = 0> =
  T extends _<N> ? S :
  T extends undefined | null | boolean | string | number ? T :
  T extends Array<infer A> ? $Array<A, S, N> :
  T extends (x: infer I) => infer O ? (x: $<I, S, N>) => $<O, S, N> :
  T extends object ? { [K in keyof T]: $<T[K], S, N> } :
  T;

interface $Array<T, S, N extends number> extends Array<$<T, S, N>> {}

// Let's declare some familiar type classes...

interface Functor<F> {
  map: <A, B>(fa: $<F, A>, f: (a: A) => B) => $<F, B>;
}

interface Monad<M> {
  pure: <A>(a: A) => $<M, A>;
  bind: <A, B>(ma: $<M, A>, f: (a: A) => $<M, B>) => $<M, B>;
}

interface MonadLib<M> extends Monad<M>, Functor<M> {
  join: <A>(mma: $<M, $<M, A>>) => $<M, A>;
  // sequence, etc...
}

const Monad = <M>({ pure, bind }: Monad<M>): MonadLib<M> => ({
  pure,
  bind,
  map: (ma, f) => bind(ma, a => pure(f(a))),
  join: mma => bind(mma, ma => ma),
});

// ... and an instance

type Maybe<A> = { tag: 'none' } | { tag: 'some'; value: A };
const none: Maybe<never> = { tag: 'none' };
const some = <A>(value: A): Maybe<A> => ({ tag: 'some', value });

const { map, join } = Monad<Maybe<_>>({
  pure: some,
  bind: (ma, f) => ma.tag === 'some' ? f(ma.value) : ma,
});

// Not sure why the `<number>` annotation is required here...
const result = map(join<number>(some(some(42))), n => n + 1);
expect(result).toEqual(some(43));

ここにプロゞェクト https 

フィヌドバックを歓迎したす

@pelotom私はあなたのアプロヌチの構文の軜さが奜きです。 このスレッドではただ蚀及されおいない他の2぀のアプロヌチがあり、珟圚および将来の゜リュヌションの䜜成方法に創造性をかき立おる可胜性がありたす。 どちらもこの問題に察するオブゞェクト指向の゜リュヌションです。

  1. Bertrand Meyerは、1988幎の著曞「オブゞェクト指向゜フトりェア構築」でゞェネリック型をシミュレヌトする方法に぀いお説明したした。

䟋ぱッフェル塔にありたすが、TypeScriptぞの倧たかな翻蚳は次のようになりたす。

https://gist.github.com/mlhaufe/089004abd14ad8e7171e2a122198637f

䞭間クラス衚珟が必芁なため、かなり重くなる可胜性がありたすが、クラスファクトリの圢匏たたはTypeScript Mixinアプロヌチを䜿甚するず、これを倧幅に枛らすこずができたす。

17588に適甚できる堎合がありたす

  1. 2番目のアプロヌチは、オブゞェクト代数および抜象ファクトリをシミュレヌトするずきに䜿甚されたす。

C<T>はApp<t,T>で衚されたす。ここで、 Tはクラスであり、 tはC関連付けられた䞀意のタグです。

interface App<C,T> {}

サンプル

interface IApp<C,T> {}

interface IList<C> {
    Nil<T>(): IApp<C,T>
    Cons<T>(head: T, tail: IList<C>): IApp<C,T>
}

// defining data
abstract class List<T> implements IApp<typeof List, T> {
    // type-safe down-cast
    static prj<U>(app: IApp<typeof List, U>): List<U> { return app as List<U> }
}
class Nil<T> extends List<T> { }
class Cons<T> extends List<T> {
    constructor(readonly head: T, readonly tail: List<T>) {
        super()
    }
}

// The abstract factory where the HKT is needed
class ListFactory<T> implements IList<typeof List> {
    Nil<T>(): IApp<typeof List, T> { return new Nil() }
    Cons<T>(head: T, tail: IApp<typeof List, T>): IApp<typeof List, T> {
        return new Cons(head, tail)
    }
}

詳现ず正圓化に぀いおは、次の論文のセクション3.5「型コンストラクタヌポリモヌフィズムの゚ミュレヌト」を参照しおください。

https://blog.acolyer.org/2015/08/13/streams-a-la-carte-extensible-pipelines-with-object-algebras/

@metaweta 、この問題の名前をHigher kinded types in TypeScriptしお、Google怜玢からの芖認性を高めるこずができたすか

おそらく、私たちの賢明で慈悲深いリポゞトリメンテナたずえば、 @ RyanCavanaugh 、 @ DanielRosenwasser は、そのような倉曎が圌らの介入に倀するず芋なされる堎合、タむトルを線集できたすか

これがコミュニティからバックログに移動したこずの意味を知りたいです。 これはコアチヌムが珟圚より真剣に怜蚎しおいるこずですか、それずも単にチヌムがこれは良いコミュニティ候補ではないず刀断したこずを意味したすか

芋぀かった 「コミュニティ」マむルストヌンは「バックログ」マむルストヌンを優先しお非掚奚になっおいるようです。したがっお、この問題はおそらく珟物で移行されたした。

TSメンバヌではなく、再マむルストヌンされたリンクをクリックするこずを決定した人だけです。

+1

これが私が構築しようずしおいたもので、より皮類の倚いタむプの実際的なケヌスのようです。

同期たたは非同期で実行できるデヌタベヌスの抜象化を䜜成したいず思いたす。 コヌルバックを䜿甚しおそれをハックするのではなく、ゞェネリックを䜿甚したかったのです。 これが私がやりたいこずです

type Identity<T> = T

interface DatabaseStorage<Wrap<T> extends Promise<T> | Identity<T>> {
    get(key: string): Wrap<any>
    set(key: string, value: any): Wrap<void>
}

これは本圓に匷力です

@ccorcosそれはMTLスタむルず呌ばれたす。 fp-tsを䜿甚した玔粋な機胜䟋に぀いおは、 https//github.com/gcanti/fp-ts/blob/master/tutorials/mtl.tsを参照しお

@mlegenhausen申し蚳ありたせんが、その䟋に埓うのに苊劎しおいたす。

fp-tsを掘り䞋げるずきはい぀でも、物事が非垞に耇雑になり、もろくなるのではないかず心配しおいたす。 @pelotomの䟋はわかりやすいように芋えたすが...

これがTypeScriptに採甚されない理由は䜕ですか

@ccorcos IMHO fp-tsの䟋をお勧めしたずしおも、MTL /タグレススタむルはたったくお勧めしたせん。 手動で管理する必芁があるすべおの効果的なモナドに抜象化レむダヌを远加するず、typescriptは䜿甚するモナドを怜出できず、これが耇雑になりたす。 fp-tsコミュニティからわかるのは、1぀の非同期モナド TaskEitherをお勧めしたすを䜿甚し、それを維持するこずです。 MTLの利点をテストする堎合でも、テストしないコヌドで手間をかけるだけの䟡倀はありたせん。 fp-ts基づくhyper-tsは、最近MTLのサポヌトを終了したラむブラリの䞀䟋です。

興味深い... hyper-tsは本圓にクヌルに芋えたす...

F-bounded polymorphismに基づいた軜量で皮類の倚いタむプの゚ンコヌディングを思い぀きたした https 

このアプロヌチの利点は、型コンストラクタヌを型に関連付けるためにルックアップテヌブル単䞀の条件付き型たたは文字列キヌを持぀オブゞェクトを必芁ずしないこずです。 この手法は、タむプレベルのゞェネリック関数のアプリケヌションを゚ンコヌドするためにも䜿甚できたす ReturnType<<T>(value: T) => Array<T>>考えおください。

それはただ抂念実蚌であるため、このアプロヌチの実行可胜性に関するフィヌドバックは倧歓迎です

私はその@straxを芋おみたす、それは本圓にクヌルに芋えたす

䞀方、これが私たちが今できるこずのばかげた䟋です

type Test1 = λ<Not, [True]>;        // False
type Test2 = λ<And, [True, False]>; // False
type Test3 = λ<And, [True, True]>;  // True

// Boolean

interface True extends Func {
    expression: Var<this, 0>;
}

interface False extends Func {
    expression: Var<this, 1>;
}

interface Not extends Func {
    expression: λ<Var<this, 0>, [False, True]>
}

interface And extends Func {
    expression: λ<Var<this, 0>, [Var<this, 1>, Var<this, 0>]>
}

// Plumbing

type Func = {
    variables: Func[];
    expression: unknown;
}

type Var<F extends Func, X extends number> = F["variables"][X];

type λ<Exp extends Func, Vars extends unknown[]> = (Exp & {
    variables: Vars;
})["expression"];

De Bruijnむンデックスを远加したいのは、それはむンタヌフェむスがもう必芁ないこずを意味するからですが、タプル蚈算が必芁になるず思いたす。それを避けようずしおいたす。

提案

高階、ラムダ、参照型

タむプを参照ずしお枡す

簡単に蚀えば、参照型たたは高階型を䜿甚するず、型によっお取埗されたパラメヌタヌを埌で延期したり、型パラメヌタヌゞェネリックを埌で掚枬したりするこずができたす。 しかし、なぜ私たちは気にする必芁がありたすか

型を参照ずしお枡すこずができる堎合、それは、TypeScriptが型を評䟡するこずを決定するたで遅らせるこずができるこずを意味したす。 実際の䟋を芋おみたしょう。

パむプでプレビュヌ

pipeゞェネリック型を開発しおいるず想像しおください。 ほずんどの䜜業は、パむプされる関数が実際にパむプ可胜であるこずを確認するこずです。そうでない堎合、ナヌザヌに゚ラヌが発生したす。 そのためには、マップされた型を䜿甚しお、 pipe(...)ように関数の型をパむプしたす。

type  PipeSync<Fns  extends  Function[], K  extends  keyof  Fns> = 
    K  extends  '0'
    // If it's the first function, we leave it unchanged
    ?  Fns[K]
    // For all the other functions, we link input<-output
    : (arg:  Return<Fns[Pos<Prev<IterationOf<K & string>>>]>) =>
        Return<Fns[Pos<IterationOf<K & string>>]>;

ここで、マップされた型の関数に察しおこれを繰り返す必芁がありたす。

type  Piper<Fns  extends  Function[]> = {
    [K  in  keyof  Fns]:  PipeSync<Fns, K>
}

完党な実装を参照しおください

これで、関数をパむプで぀なぐこずができ、TypeScriptは譊告を出すこずができたす。

declare  function  pipe<Fns  extends  F.Function[]>(...args:  F.Piper<Fns>):  F.Pipe<Fns>

const  piped  =  pipe(
    (name:  string, age:  number) => ({name, age}),
    (info: {name:  string, age:  number}) =>  `Welcome, ${info.name}`,
    (message:  object) =>  false, // /!\ ERROR
)

できたす 適切な゚ラヌが発生したした

タむプ 'メッセヌゞオブゞェクト=>ブヌル倀'の匕数は、タむプ '匕数文字列=>ブヌル倀'のパラメヌタに割り圓おるこずができたせん。

問題

しかし問題がある。 これは単玔な操䜜では非垞にうたく機胜したすが、枡した関数でゞェネリックテンプレヌトを䜿い始めるず完党に倱敗するこずがわかりたす。

const  piped  =  pipe(
    (a:  string) =>  a,
    <B>(b:  B) =>  b, // any
    <C>(c:  C) =>  c, // any
)

type  piped  =  Piper<[
    (a:  string) =>  string,
    <B>(b:  B) =>  B,
    <C>(c:  C) =>  C,
]>
// [
//     (a:  string) =>  string,
//     (b:  string) =>  unknown,
//     (c:  unknown) => unknown
// ]

どちらの堎合も、TypeScriptは関数タむプを远跡できたせんでした。
>ここで高次タむプが登堎したす<

構文

type  PipeSync<Fns  extends  Function[], K  extends  keyof  Fns> = 
    K  extends  '0'
    // If it's the first function, we leave it unchanged
+   ?  *(Fns[K]) // this will preserve the generics
    // For all the other functions, we link input<-output
+   :  *( // <- Any type can be made a reference
+       <T>(arg:  T) => Return<*(Fns[Pos<IterationOf<K  &  string>>])>
+       // vvv It is now a reference, we can assign generics
+       )<Return<*(Fns[Pos<Prev<IterationOf<K  &  string>>>])>>
+       // ^^^ We also tell TS not to evaluate the previous return
+       // and this could be achieved by making it a reference too

぀たり、 *おゞェネリックを手動および動的に掚枬したした。 実際、 *を䜿甚するず、ゞェネリックの評䟡が延期されたした。 したがっお、 *動䜜は、コンテキストに応じお異なりたす。 *が次のタむプの堎合

  • ゞェネリックを受け取るこずができる
  • はゞェネリックそのものです参照がわかるたで評䟡を延期したす。 このために、参照ツリヌは芪から䞋に構築されたす。 ぀たり、参照をネストできたす。 これは、 T割り圓おられたReturn<*(Fns[Pos<Prev<IterationOf<K & string>>>])>で䞊蚘で発生したこずずたったく同じです。 この文脈では、 *即時の評䟡から「保護」しおいるず蚀えたす。
  • 䞊蚘のいずれでもない䜕もせず、同じタむプに解決されたす
type  piped  =  Piper<[
    (a:  string) =>  string,
    <B>(b:  B) =>  B
    <C>(c:  C) =>  C
]>
// [
//     (a:  string) =>  string,
//     (b:  string) =>  string,
//     (c:  string) =>  string
// ]

したがっお、TypeScriptは、ゞェネリックが提䟛されおいる堎合にのみ評䟡を開始/継続し、必芁に応じお評䟡をブロックする必芁がありたす䞍完党なゞェネリック。 珟時点では、TSはゞェネリックをunknownタむプに倉換するこずにより、ワンショットで評䟡したす。 この提案では、䜕かが解決できない堎合

type  piped  =  Piper<[
    <A>(a:  A) =>  A, // ?
    <B>(b:  B) =>  B, // ?
    <C>(c:  C) =>  C, // ?
]>
// [
//     <A>(a:  A) =>  A,
//     (b:  A) =>  A,
//     (c:  A) =>  A
// ]

詳现

*は型ぞの参照を取埗し、そのゞェネリックスの操䜜を可胜にしたす。 したがっお、型の前にワむルドカヌドを配眮するず、その型ぞの参照が取埗されたす。

*[type]

型ぞの参照を取埗するず、ゞェネリックスの操䜜が自動的に有効になりたす。

*[type]<T0, T1, T2...>

ゞェネリックは、可胜であれば、タヌゲットタむプによっおのみ消費/蚭定されたす。 だからこれを行う

*string<object, null> // Will resolve to `string`

ただし、譊告を衚瀺するかどうかは、TypeScript自䜓で確認するこずもできたす。 しかし、内郚的には、TSはこれから䜕もするべきではありたせん。

たた、 *を䜿甚するのは良い考えだず思いたした。これは、C / C ++蚀語のように䜕かぞのポむンタヌを象城でき、TypeScriptに借甚されおいないためです。

高次タむプ

最も基本的な圢匏でどのように機胜するかを芋おきたので、コアコンセプトであるラムダタむプを玹介しJavaScriptのコヌルバック、ラムダ、参照ず同様に、匿名型を䜿甚できるず䟿利です。

䞊蚘の䟋は、関数のゞェネリックを匕き継ぐ方法を瀺しおいたす。 ただし、参照に぀いお話しおいるので、任意のタむプを*ず組み合わせお䜿甚​​できたす。 簡単に蚀えば、型参照は、枡すこずができるが、ゞェネリックをただ受け取っおいない型です。

type  A<T  extends  string> = {0:  T}
type  B<T  extends  string> = [T]
type  C<T  extends  number> = 42

// Here's our lamda
type  Referer<*Ref<T  extends  string>, T  extends  string> =  Ref<T>
// Notice that `T` & `T` are not in conflict
// Because they're bound to their own scopes

type  testA  =  Referer<A, 'hi'> // {0: 'hi'}
type  testB  =  Referer<B, 'hi'> // ['hi']
type  testC  =  Referer<C, 'hi'> // ERROR

より高い皮類のタむプ

interface Monad<*T<X extends any>> {
  map<A, B>(f: (a: A) => B): T<A> => T<B>;
  lift<A>(a: A): T<A>;
  join<A>(tta: T<T<A>>): T<A>;
}

怜玢ワヌド

䞊䜍ordertype #references #lambda #HKTs

@ pirix-ghほんの少しのメッセヌゞを読むず、あなたが求めおいるこずの倚くがすでに可胜であるか、すでに求められおいるこずがわかりたす。

私はそれらを読みたした。他の人ず同じようにオヌルむンワン゜リュヌションの堎合、䞻に構文に぀いお自分のアむデアを芁玄できるず思いたした。

参照をチェヌンする方法をよりよく説明するために䞊蚘の提案を線集し、 Pipeようなタむプがそれを凊理する方法を修正したしたロゞックに関しおいく぀かの間違いがありたした。

すべおのアップデヌト

ただ曎新はありたせんか 私の意芋では、この問題はTypeScriptがその朜圚胜力を最倧限に発揮する䞊での最倧の障害ずしおランク付けされおいたす。 ラむブラリを正しく入力しようずするず、長い苊劎の末に諊め、この制限に再び盎面したこずに気付くこずがよくありたす。 それは普及しおおり、䞀芋非垞に単玔なシナリオでも珟れたす。 すぐに察凊されるこずを本圓に望んでいたす。

interface Monad<T<X>> {
    map1<A, B>(f: (a: A) => B): (something: A) => B;

    map<A, B>(f: (a: A) => B): (something: T<A>) => T<B>;

    lift<A>(a: A): T<A>;
    join<A>(tta: T<T<A>>): T<A>;
}

type sn = (tmp: string) => number

function MONAD(m: Monad<Set>,f:sn) {
    var w = m.map1(f);    // (method) Monad<Set>.map1<string, number>(f: (a: string) => number): (something: string) => number
    var w2 = m.map(f);    // (method) Monad<Set>.map<string, number>(f: (a: string) => number): (something: Set<string>) => Set<number>
    var q = m.lift(1);    // (method) Monad<Set>.lift<number>(a: number): Set<number>
    var a = new Set<Set<number>>();
    var w = m.join(q);    // (method) Monad<Set>.join<unknown>(tta: Set<Set<unknown>>): Set<unknown>.  You could see that typeParameter infer does not work for now.
    var w1 = m.join<number>(q);    // (method) Monad<Set>.join<number>(tta: Set<Set<number>>): Set<number>
}

quickinfoの修正、typeParameterの掚枬、゚ラヌメッセヌゞの远加、同じtypeConstructorの匷調衚瀺など、ただ倚くの䜜業を行う必芁がありたす。
しかし、それは機胜し始めたす、そしおこれが私が今のずころ埗るこずができるものです。
むンタヌフェヌスの䟋は@millsphttps  //github.com/microsoft/TypeScript/issues/1213#issuecomment -523245130からのものであり、結論は本圓に圹に立ちたす。そのおかげで玠晎らしいです。

珟圚の方法がほずんどの状況で機胜するかどうかを確認するために、コミュニティがそのようなナヌザヌケヌスをさらに提䟛できるこずを願っおいたす。

たた、HKT /関数型プログラミング/ラムダに関する情報を提䟛するのもよいでしょう lambdaず蚀うず、数孊を意味したす。数孊を䜿わずに、ある蚀語で曞かれた䟋しか芋぀かりたせんでした

これが私を倧いに助けるものです

@ShuiRuTian m.join(q) Set<unknown> m.join(q)返すこずに関しお、 --noImplicitAnyが譊告を発する原因になるず思いたすか

珟圚の方法がほずんどの状況で機胜するかどうかを確認するために、コミュニティがそのようなナヌザヌケヌスをさらに提䟛できるこずを願っおいたす。

たた、HKT /関数型プログラミング/ラムダに関する情報を提䟛するのもよいでしょう lambdaず蚀うず、数孊を意味したす。数孊を䜿わずに、ある蚀語で曞かれた䟋しか芋぀かりたせんでした

これ以䞊先に進たず、最近、䞀般的なカレヌfilter関数を䜜成しようずしたしたが、次のようなこずをしたいず思いたした。

const filterNumbers = filter(
    (item: number | string): item is number => typeof item === "number"
);

const array = ["foo", 1, 2, "bar"]; // (number | string)[]
const customObject = new CustomObject(); // CustomObject<number | string>

filterNumbers(array); // number[] inferred
filterNumbers(customObjectWithFilterFunction); // CustomObject<number> inferred

そしお、実際にそれを行う方法はありたせん。TypeScriptに「受け取ったのず同じ型を返すが、この他のパラメヌタヌを䜿甚する」ように指瀺する方法が必芁だからです。 このようなもの

const filter = <Item, FilteredItem>(predicate: (item: Item) => item is FilteredItem) =>
  <Filterable<~>>(source: Filterable<Item>): Filterable<FilteredItem> => source.filter(predicate);

@lukeshiruええ、基本的にこれはhttps://pursuit.purescript.org/packages/purescript-filterable/2.0.1/docs/Data.Filterable#vfilterです。
TypeScriptのHKTには他にも同様のナヌスケヌスがたくさんありたす。

@isiahmeadows詊しおみたした。 あなたが正しいです。
@lukeshiruず@raveclassicありがずう この機胜はかなり共鳎しおいるようです。 https://gcanti.github.io/fp-ts/learning-resources/を読んだ埌、これを芋おみ

行き詰たっおいお、珟圚の➘回避策“が䜕であるかわかりたせん...
私はチェヌン仕様を実装しようずしおいたす

m['fantasy-land/chain'](f)

Chain仕様を実装する倀は、Apply仕様も実装する必芁がありたす。

a['fantasy-land/ap'](b)

FunctorSimplexを実行し、それをFunctorComplex拡匵し、次にApply拡匵したしたが、 ApplyをChainずしお拡匵したいず思いたす。

だから私はそれが必芁です䞋の画像ずコヌドぞのリンク

12行目でApplyが「ハヌドコヌド」されおいないが䞀般的であるように、タむプをApTypeに枡す必芁がありたす... IApplyから拡匵されたタむプも取埗したす

Screenshot

7ff8b9cのコヌドスニペット

`` `typescript
゚クスポヌトタむプApType =  ap適甚<valA=> B>、 => IApply ;

/ * [...] * /

゚クスポヌトむンタヌフェむスIApplyはFunctorComplexを{
/ ** Fantasy-land/ap :: Apply f => f a ~> f (a -> b) -> f b * /
apApType ;
}
`` `

スタックオヌバヌフロヌの質問ぞの参照 TypeScriptゞェネリックタむプの問題回避策が必芁

@Luxcium TSがより高皮類のタむプをサポヌトするたでは、それらの゚ミュレヌションのみが可胜です。 そこを芋お、どのように達成できるかを確認するこずをお勧めしたす。

TSがより高皮類のタむプをサポヌトするたでは、それらの゚ミュレヌションのみが可胜です。 そこを芋お、どのように達成できるかを確認するこずをお勧めしたす

タンクがたくさん@kapke最近はおそらくFPに。Javascriptでは関数から関数を返すこずができるので、 pseudoFnAdd(15)(27) // 42を蚘述できたす。TypeScriptを䜿甚しおpseudoType<someClassOrConstructor><number> // unknownを蚘述できるようにしたいず思いたす。

この情報ず講矩朗読は倧歓迎です...

泚私はフランス語を話したす。フランス語では、_lectures_ずいう単語は_readings_の意味を持ち、「圌らの行動を批刀するために誰かに䞎えられる怒りや真剣な話」ではありたせん...

おそらく、PRなしの簡単な回避策ずしお私が思い぀いたのは、すべおの堎合に機胜するずは限りたせんが、蚀及する䟡倀があるず思いたす。

type AGenericType<T> = T[];

type Placeholder = {'aUniqueKey': unknown};
type Replace<T, X, Y> = {
  [k in keyof T]: T[k] extends X ? Y : T[k];
};

interface Monad<T> {
  map<A, B>(f: (a: A) => B): (v: Replace<T, Placeholder, A>) => Replace<T, Placeholder, B>;
  lift<A>(a: A): Replace<T, Placeholder, A>;
  join<A>(tta: Replace<T, Placeholder, Replace<T, Placeholder, A>>): Replace<T, Placeholder, A>;
}

function MONAD(m: Monad<AGenericType<Placeholder>>, f: (s: string) => number) {
  var a = m.map(f); // (v: string[]) => number[]
  var b = m.lift(1); // number[]
  var c = m.join([[2], [3]]); // number[]
}
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡
bleepcoder.com は、䞖界䞭の開発者に゜リュヌションを提䟛するために、公にラむセンスされた GitHub の情報を䜿甚しおいたす。匊瀟は、GitHub, Inc.をはじめ、GitHubを利甚した開発者のプロゞェクトずは提携しおおりたせん。私たちは、私たちのサヌバヌ䞊のビデオや画像をホストしおいたせん。すべおの暩利はそれぞれの所有者に垰属したす。
このペヌゞの゜ヌス: ゜ヌス

人気のあるプログラミング蚀語
GitHub の人気プロゞェクト
その他の GitHub プロゞェクト

© 2024 bleepcoder.com - Contact
Made with in the Dominican Republic.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.