Javascript TypeScript 中的嵌套对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38245081/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:13:58  来源:igfitidea点击:

Nested objects in TypeScript

javascripttypescript

提问by Samuel

How to declare JavaScript like nested objects in TypeScript?

如何在 TypeScript 中像嵌套对象一样声明 JavaScript?

let endpoints = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

The following does not work:

以下不起作用:

private endpoints: Object = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

Throws:

抛出:

error TS2339: Property 'auth' does not exist on type 'Object'.

error TS2339: Property 'auth' does not exist on type 'Object'.

回答by Nitzan Tomer

You can use interfaces:

您可以使用接口:

interface EndpointAuth {
    login: string;
}

interface Endpoint {
    auth: EndpointAuth;
}

let endpoints: Endpoint = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

(code in playground)

操场上的代码

You can also use types instead of interfaces:

您还可以使用类型而不是接口:

type EndpointAuth = {
    login: string;
}

type Endpoint = {
    auth: EndpointAuth;
}

(code in playground)

操场上的代码

Or "inline":

或“内联”:

let endpoints: { auth: { login: string } } = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

You can combine them of course.

你当然可以组合它们。



Edit

编辑

As you wanted the answer to explain why it did not work with Object:

正如你想要的答案来解释为什么它不工作Object

Defining a variable to be of type Objectis (in most cases) not what you really want to do, usually what you mean is any, as this:

将变量定义为类型Object(在大多数情况下)不是您真正想要做的,通常您的意思是any,如下所示:

var endpoints2: any = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

Won't fail (just like it won't if you do not specify a type).
Defining a variable as Objectis the same as defining it as {}which is an empty object, and that's usually not what you're after, and it will work for only things like:

不会失败(就像不指定类型不会失败一样)。
将变量定义为Object与将其定义为{}空对象相同,这通常不是您所追求的,它仅适用于以下情况:

let o1: Object = {};
let o2: Object = Object.create(null);

But using anydoesn't help you too much because then you basically tell the compiler not to bother with type safety, it will let you do what ever with the variable without letting you know that there are errors:

但是使用any对你没有太大帮助,因为你基本上告诉编译器不要打扰类型安全,它会让你对变量做任何事情而不会让你知道有错误:

let o: any = { x: 3, y: 6 };
console.log(o.z.toString());

Won't fail in compilation but will fail at run time:

在编译时不会失败,但会在运行时失败:

Uncaught TypeError: Cannot read property 'toString' of undefined

未捕获的类型错误:无法读取未定义的属性“toString”

This will fail in compilation:

这将在编译中失败:

let o: { x: number, y: number } = { x: 3, y: 6 };
console.log(o.z.toString());

回答by Ruben Karapetyan

You can declare an Interface.

您可以声明一个接口。

For your case

对于您的情况

interface IEndpoints
{
 auth: {
  login: string;
 }
}
private endpoints: IEndpoints = {
  auth: {
    login: "http://localhost:8079/auth/login"
  }
};

回答by Amir Popovich

If you want to be type safe need to create your custom class\interface:

如果你想类型安全需要创建你的自定义类\接口:

interface IMyInterface
{
    auth: IAuth;
}

interface IAuth
{
    login: string;
}

private endpoints: IMyInterface= {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
};

Your error is because the your declaring endpoints of type Object, and Object doesn't have an auth property.

您的错误是因为您声明的类型为 Object 的端点,而 Object 没有 auth 属性。

回答by Flaff

I don't know which typescript version you were using in the past, but currently, this is supported

我不知道您过去使用的是哪个打字稿版本,但目前支持

interface Endpoints {
  [path: string]: Endpoints | string
}

const endpoints: Endpoints = {
    auth: {
        login: "http://localhost:8079/auth/login"
    }
}