如何在 TypeScript 中指定类型化对象文字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19456105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I specify a typed object literal in TypeScript?
提问by Trident D'Gao
I there a way to apply type annotation to an object literal directly? By directly I mean without having to assign it to a variable which is type annotated. For example: I know I can do it like this:
我有没有办法将类型注释直接应用于对象文字?直接我的意思是不必将其分配给类型注释的变量。例如:我知道我可以这样做:
export interface BaseInfo { value: number; }
export interface MyInfo extends BaseInfo { name: string; }
function testA(): BaseInfo = {
const result: MyInfo = { value: 1, name: 'Hey!' };
return result;
}
I also can do it like this:
我也可以这样做:
function testB(): BaseInfo = {
return { value: 1, name: 'Hey!' };
}
But what I need is something like:
但我需要的是这样的:
function testC(): BaseInfo = {
return { value: 1, name: 'Hey!' }: MyInfo; // <--- doesn't work
}
Or like this:
或者像这样:
function testD(): BaseInfo = {
return MyInfo: { value: 1, name: 'Hey!' }; // <--- doesn't work
}
采纳答案by Trident D'Gao
Answer is to use the identity function:
答案是使用恒等函数:
function to<T>(value: T): T { return value; }
const instance = to<MyInfo>({
value: 1,
name: 'Hey!',
});
回答by Ryan Cavanaugh
Intellisense for members of object literals is provided by the contextual type(see section 4.19 of the spec) of the expression.
对象字面量成员的智能感知由表达式的上下文类型(参见规范的第 4.19 节)提供。
You can acquire a contextual type in a variety of ways. Some of the most common places where a contextual type is applied are:
您可以通过多种方式获取上下文类型。应用上下文类型的一些最常见的地方是:
- The initializer of a variable with a type annotation
- The expression in a
return
statement in a function or getter with a return type annotation - The expression in a type assertion expression (
<T>expr
)
- 带有类型注解的变量的初始化器
return
带有返回类型注释的函数或 getter 语句中的表达式- 类型断言表达式 (
<T>expr
) 中的表达式
In your example, you can use a type assertion to force your object literal to have a contextual type:
在您的示例中,您可以使用类型断言来强制您的对象文字具有上下文类型:
function testB() {
return <IMyInfo>{ name: 'Hey!' };
}
回答by TmTron
To be really type-safe there are these ways:
要真正实现类型安全,有以下几种方法:
Example interface:
示例界面:
interface IFoo {
firstName: string;
lastName: string;
}
specify the function result type
指定函数结果类型
function useResultType(): IFoo {
return {
firstName: 'mars'
// compile error, when lastName is missing
// , lastName: 'xx'
};
}
return a constant
返回一个常数
function resultVariable() {
const result: IFoo = {
firstName: 'mars'
// compile error, when lastName is missing
// , lastName: 'xx'
};
return result;
}
use a generic identity function(note: rxjs has an identityfunction)
使用通用标识函数(注意:rxjs 有标识函数)
function ident<T>(value: T): T {
return value;
}
function identityFunction() {
return ident<IFoo>({
firstName: 'mars'
// compile error, when lastName is missing
// , lastName: 'xx'
});
}
when you just use type assertions- the compiler will not show an error when you return any other type (e.g. in the examples, I "forgot" the lastName
member)
当您只使用类型断言时- 当您返回任何其他类型时,编译器不会显示错误(例如,在示例中,我“忘记”了该lastName
成员)
function asCast() {
return {
firstName: 'mars'
// NO error
} as IFoo;
}
function cast() {
return <IFoo>{
firstName: 'mars'
// NO error
};
}
you can check the examples in the Typescript Playground
您可以查看Typescript Playground 中的示例
回答by David Norman
Remember that that interfaces follow duck typing: if an object looks like it matches the interface, it does match the interface.
请记住,接口遵循鸭子类型:如果一个对象看起来与接口匹配,则它确实与接口匹配。
So
所以
function testB(): IBaseInfo = {
return { name: 'Hey!' };
}
is exactly the same as
完全一样
function testA(): IBaseInfo = {
var result: IMyInfo = { name: 'Hey!' };
return result;
}
Either way, the returned object looks like an IMyInfo, so it is an IMyInfo. Nothing that happens inside the function affects what interfaces it matches.
无论哪种方式,返回的对象看起来都像一个 IMyInfo,所以它是一个 IMyInfo。函数内部发生的任何事情都不会影响它匹配的接口。
However, in your examples, the return value of the function is IBaseInfo, so the compiler and intellisense will assume that the object is just an IBaseInfo. if you want the caller of the function to know that the return value is an IMyInfo, you need to make the return value of the function IMyInfo:
但是,在您的示例中,该函数的返回值是 IBaseInfo,因此编译器和智能感知将假定该对象只是一个 IBaseInfo。如果想让函数的调用者知道返回值是一个 IMyInfo,则需要使函数 IMyInfo 的返回值:
function testB(): IMyInfo = {
return { name: 'Hey!' };
}
or using type inference, simply
或者使用类型推断,简单地
function testB() = {
return { name: 'Hey!' };
}
回答by Alex Dresko
Your first and second examples fail, so yo can't do that. :)
你的第一个和第二个例子失败了,所以你不能这样做。:)
Pretty sure you don't have to specify any types on your literal. As long as your literal meets the interface requirements, you're good.
很确定您不必在文字上指定任何类型。只要您的文字满足接口要求,就很好。
interface IMyInfo { name: string; }
var asdf = {
name: "test"
}
var qwer: IMyInfo = asdf;
If you want intellisense, you have to do something like:
如果您想要智能感知,则必须执行以下操作:
Or maybe this is what you're looking for. Intellisense works here, at least on the playground.
或者,这可能就是您正在寻找的。智能感知在这里工作,至少在操场上。
Or maybe this. :)
或者也许这个。:)