有时打字稿无法推断lambda或方法的返回类型,我想手动指定它以获得类型安全。
问题出现在例如使用promises或更复杂的回调时(例如使用parsimmon
解析库)。
我没有找到一种方法来指定返回变量的类型来获取类型检查,除非通过创建局部变量:
interface ITest {
x: number;
y: string;
}
// type checks, i'd prefer it doesn't
function f1() {
return {x:5} as ITest;
}
// type checks, i'd prefer it doesn't
// (I understand it's a cast, just to show also that doesn't help)
function f2() {
return <ITest>{x:5};
}
// correctly fails to type-check
function f3() {
const x: ITest = {x:5};
return x;
}
还有另一种方法可以在不创建局部变量的情况下进行类型检查吗?我当然知道我可以输入function f4(): ITest
,但我的用例看起来更像是这样:
return P.string(" for ")
.then(P.takeWhile(c => c !== ' ').skip(P.string(" in ")))
.chain(value => P.takeWhile(c => c !== ' ')
.chain(array => parseNgOptionsTrackBy().atMost(1)
.map(trackBy => {
// variable created solely for type-checking
const r: NgOptionsData = {
select: expressions.select,
label: expressions.label,
value: value,
array: array,
trackexpr: trackBy ? trackBy[0] : undefined
};
return r;
})));
或:
return new Promise((resolve, reject) => {
// some code, then variable created solely for type-checking
const result: ViewInfo = {
fileName: fileName,
ngModuleName: ngModuleName,
controllerName: controllerName,
controllerViewInfos: viewInfos};
resolve(result);
});
换句话说,我深入一些lambda并指定一个返回类型并不那么简单。
更新我看到有些人怀疑打字稿实际上无法推断resolve
的承诺。幸运的是我的应用程序是OSS。我做了一个提交,在一些分支中演示了这个问题:
https://github.com/emmanueltouzery/ng-typeview/tree/so_question
检查the last commit on that branch。正如你所看到的,我从我正在填充的结构中删除了一个字段(我想要一个构建错误!!)但它构建得很好。我做了指定函数的返回类型Promise<ControllerScopeInfo>
。
This is type-unsafe。
如果要构建,则必须运行npm install
,然后tsc
。虽然大概你可以检查源和tsconfig并且信任我在建筑物上。
答案 0 :(得分:1)
你的意思是:
return new Promise((resolve, reject) => {
resolve({
fileName: fileName,
ngModuleName: ngModuleName,
controllerName: controllerName,
controllerViewInfos: viewInfos
} as ViewInfo);
});
这很奇怪,可能是一个错误,因为如果添加一个可选属性:
interface ViewInfo {
fileName: string;
ngModuleName: string;
controllerName: string;
controllerViewInfos: ViewInfo[];
dummy?: any;
}
然后做:
return Promise.resolve({
fileName: "fileName 2",
ngModuleName: "ngModuleName 2",
controllerName: "controllerName 2",
dummy: 3
});
你会收到错误:
输入'Promise&lt; {fileName:string; ngModuleName:string; controllerName:string;假人:数字; }&GT;”不能分配给类型 '诺言'。
输入'{fileName:string; ngModuleName:string; controllerName: 串;假人:数字; }'不能分配给'ViewInfo'类型。
类型'{fileName:string;}中缺少属性'controllerViewInfos'; ngModuleName:string; controllerName:string;假人:数字; }”。
它有可能是设计的,但我现在想不出一个理由。尝试提交问题,如果你这样做,请分享链接。
同时,您可以为要返回的这些类型创建工厂函数:
function viewInfoFactory(fileName: string, ngModuleName: string, controllerName: string, controllerViewInfos: ViewInfo[]): ViewInfo {
return {
fileName,
ngModuleName,
controllerName,
controllerViewInfos
}
}
在该功能中,您将获得您所追求的类型安全性,同时,根据您的代码,它可以使其更具可读性。
答案 1 :(得分:1)
根据要求
在上面的一个例子中:
function x() /*: Promise<{}>*/ {
// declared as Promise<{}>
return new Promise((resolve, reject) => {
// ViewInfo assignable to {}
resolve(
<ViewInfo> {
fileName: fileName,
ngModuleName: ngModuleName,
controllerName: controllerName,
controllerViewInfos: viewInfos}
);
})
};
推断函数是
()=> Promise<{}>
由于:
CORS Generic ,并希望在构造函数中指定 T ,
或默认为Promise&lt; {}&gt;
解析ViewInfo也是合法的
基于Promise,
可分配给{}
这可以解释为什么示例代码按设计工作
答案 2 :(得分:0)
您可以声明某些承诺的返回类型,例如Promise<string>
function returnStringPromise(): Promise<string> {
return new Promise((resolve, reject) => {
resolve("string");
})
}
或
return <Promise<string>> new Promise((resolve, reject) => resolve("string"));
或
return new Promise((resolve, reject) => resolve("string")) as Promise<string>;