为什么条件类型在通用函数中不起作用?

时间:2018-07-12 08:20:49

标签: typescript

为什么TypeScript无法使用对泛型函数的类型参数的约束来推断参数的类型或返回类型?

X = # train data
y = # train labels

# applying SMOTE

from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=42)
X_balanced, y_balanced = sm.fit_sample(X, y)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split (X_balanced, y_balanced, test_size = 0.1) 
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform (X_test)
from sklearn.svm import SVC
clf = SVC(kernel = 'linear')
clf.fit (X_train, y_train.ravel())
y_pred = clf.predict(X_test)
from sklearn.metrics import confusion_matrix
cm = confusion_matrix (y_test, y_pred)
from sklearn.model_selection import cross_val_score
accuracies = cross_val_score (estimator = clf, X = X_train, y = y_train, cv = 10)
accuracies.mean()
accuracies.std()
from sklearn.model_selection import GridSearchCV
parameters = [{'C':[1, 10, 100], 'kernel':['linear']}, 
              {'C':[1, 10, 100], 
               'kernel':['rbf'], 
               'gamma': [0.05, 0.001, 0.005]}]
grid_search = GridSearchCV (estimator = clf, param_grid = parameters, scoring = 'accuracy', cv = 10)
grid_search = grid_search.fit (X_train,y_train)
best_accuracy =  grid_search.best_score_ 
print (best_accuracy)
best_parameters = grid_search.best_params_
print (best_parameters)

除了分叉TS以外,还有什么方法可以达到预期的结果?

(使用TS 2.9.2)

2 个答案:

答案 0 :(得分:1)

在通常需要通用类型的情况下分配值通常是行不通的,打字稿假定该值将不兼容。这是因为当我们具有通用类型时,该类型表示T的任何可能的子类型。

现在在这种情况下,很明显T将始终为"Y",因为对T已有约束,但是打字稿不会尝试推论得出。更加明显的情况将不起作用,因为在这种情况下,打字稿根本无法进行任何分析:

function isNum<T extends number>(x: T): T extends number ? "Y" : "Y" {
    return "Y"; // still an error 
}

唯一的解决方案是使用类型断言:

function isNum<T extends number>(x: T): T extends number ? "Y" : "N" {
    return "Y" as any;
}

修改

@jcalz指出,另一个很好的选择是使用多个重载(或更具体地说,是使用条件类型的公共重载,而不是使用条件类型的实现)

function isNum<T extends number>(x: T): T extends number ? "Y" : "N"
function isNum(x: number): "Y" | "N" {
    return "Y";
}

答案 1 :(得分:0)

否,Typescript尚不支持条件返回类型。对于您的情况,您可以做以下几件事:

以枚举形式返回类型

enum YesNo {
  Y= 'Y',
  N= 'N'
}
function isNum<T extends Number>(x:T) : YesNo {
  return x as any instanceof Number ? YesNo.Y : YesNo.N;
}

严格的返回类型

function isNum<T extends Number>(x:T) : 'Y' | 'N' {
  return x as any instanceof Number ? 'Y' : 'N';
}

如果要将返回类型指定为特定类型

interface ANumber extends Number {
  ...
}
interface BNumber extends Number {
  ...
}
function isNum<T extends Number>(x:T) : ANumber | BNumber {
  return x;
}

注意:上面的接口也可以是类。