![](/img/trans.png)
[英]Why does method chaining in TypeScript cause generic type inference to fail?
[英]typescript: generic constraints cause type inference to pick wrong candidate?
TypeScript版本: 2.6.0-dev.20170826和2.4.2
我想知道我是否遇到了一些打字稿推斷錯誤/限制,或者我的代碼是否完全錯誤。 如果代碼實際上是有效的,並且是類型推斷問題,我將向打字稿github報告一個錯誤。
我試圖限制“ Set
構建器接受僅正確定義了相等性的類型(以避免出現此問題 )。
奇怪的
declare module 'strange' {
export type WithEquality = string|number|boolean|{equals(other: any): boolean; hashCode(): number;};
export interface Set<T> {
add(other: T): Set<T>;
}
export function makeSetUnsafe<V>(...vals: V[]): Set<V>;
export function makeSet<V extends WithEquality>(...vals: V[]): Set<V>;
}
陌生人
///<reference path="./strange.d.ts"/>
import * as S from 'strange';
const x = S.makeSetUnsafe(1,2,3);
x.add(4);
const y = S.makeSet(1,2,3);
y.add(4);
預期的行為:根據我的理解,代碼應進行編譯。 Typescript應該為兩個示例都推斷出number
作為類型,並且因為number
是WithEquality
一個選項,並且約束是T extends WithEquality
,所以一切都很好。
實際行為:對makeSetUnsafe
的調用可以makeSetUnsafe
編譯,但是對makeSet
的調用失敗,並出現以下錯誤:
strange.ts(9,7): error TS2345: Argument of type '4' is not assignable to parameter of type '1 | 2 | 3'.
添加泛型約束以檢查Set
接口的泛型類型是否具有WithEquality
擴展, WithEquality
導致推理選擇1|2|3
而不是T
的number
。
通過const y = S.makeSet<number>(1,2,3);
顯式地指定類型const y = S.makeSet<number>(1,2,3);
使其構建,因此添加通用約束似乎會使類型推斷選擇其他類型。
實際上,即使更簡單,我也可以重現該問題
export type WithEquality = number;
一個很好的答案將解釋為什么此代碼是錯誤的,希望給出一個打字稿實現,以允許在類型推斷有效的情況下表達這些約束,或者確認這是打字稿的局限性。
至於發生這種情況的原因,請檢查此問題的答案:
約束為基本類型或聯合類型的類型變量,不能分配給它 。
您可以這樣解決:
export function makeSet<V>(...vals: Array<V & WithEquality>): Set<V>;
接着:
const y = makeSet2(1,2,3);
y.add(4); // fine
const z = makeSet(/a*/); // error
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.