如何在不存储 TypeScript 的情况下进行内联类型检查?

Sep*_*eed 6 typechecking typescript

我有一些界面

ITestInterface {
  foo: string;
}
Run Code Online (Sandbox Code Playgroud)

我想将此接口的实例作为参数传递给函数。该函数将采用任何对象类型,因此它本身不会进行类型检查。为了确保对象的类型正确,我可以使用存储:

const passMe: ITestInterface = { foo: "bar" };
someFunction(passMe);
Run Code Online (Sandbox Code Playgroud)

但我希望有一种方法可以内联创建参数,同时仍然进行类型检查。

// made up example syntax
someFunction({ foo: "bar" } istype ITestInterface);
Run Code Online (Sandbox Code Playgroud)

有没有像上面的内联示例这样的好方法?

我尝试过使用 as,但它不限制类型。例如,以下内容是有效的。

someFunction({ foo: "bar", hello: true } as ITestInterface);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我可以做的另一件事是修改someFunction模板,但这不是我认为很好的解决方案。我不会永远拥有这个特权。

someFunction<TYPE>(arg: TYPE) {
  // modify function definition
}

someFunction<ITestInterface>({foo: "bar"});
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 4

您正在寻找的特定功能(例如“任意表达式的类型注释”)在 TypeScript 中不存在。目前有一个开放的建议,标记为“需求建议”,因此,如果您的想法令人信服并且与现有的不同,您可能想要给出一个或描述您的想法。但在我看来,似乎没有人在做这件事,所以如果我是你,我就不会屏住呼吸。


这里有多种方法,每种方法都有自己的问题。

正如您所看到的,最简单的方法是使用类型断言。这可以防止您传入完全不相关的类型:

// assertion
someFunction({ foo: "bar" } as ITestInterface); // okay as expected
someFunction({ unrelatedThing: 1 } as ITestInterface); // error as expected
Run Code Online (Sandbox Code Playgroud)

ITestInterface它还允许额外的属性(这仍然是合理且类型安全的,不保证类型的对象具有其他属性......它可能会让您感到惊讶,因为您期望进行过多的属性检查,但这些只会在某些时候发生):

someFunction({ foo: "bar", hello: true } as ITestInterface); // okay by design,
// excess properties are allowed
Run Code Online (Sandbox Code Playgroud)

但这里最重要的问题是类型断言让您不安全地缩小类型,因此以下不会是错误:

someFunction({} as ITestInterface); // no error ?! assertions also NARROW types
Run Code Online (Sandbox Code Playgroud)

另一种方法是创建一个辅助函数,isType如下所示:

// helper function
const isType = <T>(x: T) => x;
Run Code Online (Sandbox Code Playgroud)

这几乎完全符合您的要求:

someFunction(isType<ITestInterface>({ foo: "bar" })); // okay as expected
someFunction(isType<ITestInterface>({ unrelatedThing: 1 })); // error as expected

someFunction(isType<ITestInterface>({ foo: "bar", hello: true })); // error as you want
someFunction(isType<ITestInterface>({})); // error as everyone wants
Run Code Online (Sandbox Code Playgroud)

但是,正如您所说,这对您来说可能不值得。大多数运行时引擎都会很乐意内联函数,x => x所以我不认为这是性能问题。但这可能是一个优雅问题,这取决于你。


无论如何,这些是我能做的最好的了。希望有帮助。祝你好运!

链接到代码