使用声明文件覆盖赛普拉斯打字稿
Overriding Cypress typescript using declaration file
我正在阅读这篇关于 Cypress 的 article。在最后一部分,作者在调用 Cypress.env
.
时覆盖了 typescript 推断的类型
这是我想了解的片段。
export { };
declare global {
namespace Cypress {
export interface Cypress {
/**
* Returns all environment variables set with CYPRESS_ prefix or in "env" object in "cypress.json"
*
* @see https://on.cypress.io/env
*/
env(): Partial<EnvKeys>;
/**
* Returns specific environment variable or undefined
* @see https://on.cypress.io/env
* @example
* // cypress.json
* { "env": { "foo": "bar" } }
* Cypress.env("foo") // => bar
*/
env<T extends keyof EnvKeys>(key: T): EnvKeys[T];
/**
* Set value for a variable.
* Any value you change will be permanently changed for the remainder of your tests.
* @see https://on.cypress.io/env
* @example
* Cypress.env("host", "http://server.dev.local")
*/
env<T extends keyof EnvKeys>(key: T, value: EnvKeys[T]): void;
/**
* Set values for multiple variables at once. Values are merged with existing values.
* @see https://on.cypress.io/env
* @example
* Cypress.env({ host: "http://server.dev.local", foo: "foo" })
*/
env(object: Partial<EnvKeys>): void;
}
}
}
interface EnvKeys {
'boards': Array<{
created: string;
id: number;
name: string;
starred: boolean;
user: number;
}>;
'lists': Array<{
boardId: number
title: string
id: number
created: string
}>;
}
我在这段代码中有几个问题:
- typescript 如何知道这个名为
env.d.ts
的文件?我知道如果文件与文件同名,则打字稿会自动知道类型(例如 command.ts
-> command.d.ts
- 这里
export {}
有什么用。如果我评论这个,Vscode 抱怨。
- 为什么我们必须在这里添加
declare global
,而原始的 Cypress 打字稿以 declare namespace Cypress
开头?
我不是打字专家,但这是我的看法
1.当它被命名为 env.d.ts
时,打字稿如何知道这个文件
在tsconfig.json
你有
include": [
"**/*.ts"
]
这意味着 env.d.ts
包含在编译中。
运行 tsc --listFiles --noEmit
查看包含的内容。
2。这里的export {}有什么用
您正在合并命名空间,文档 Merging Namespaces 说
To merge the namespaces, type definitions from exported interfaces declared in each namespace are themselves merged.
进一步
Non-exported members are only visible in the original (un-merged) namespace. This means that after merging, merged members that came from other declarations cannot see non-exported members.
所以,它是信息隐藏 - 就像 public vs 私有变量。
糟糕,回答错误
我刚意识到你想知道第一行。
请看这个回答
I think the trick is just that an "external module" is a file containing an import or export statement, so this makes it an "external module".
3。为什么我们要加上 declare global
You can also add declarations to the global scope from inside a module
编写测试时,您可以使用 Cypress.Commands.add()
、cy.get()
、it()
等,无需导入任何内容,因为它们是全局声明的。
要与全局赛普拉斯界面合并,您的增强功能也必须声明为全局。
要看效果,改env.d.ts
declare module "env" {
namespace Cypress {
和addTaskApi.ts
Cypress.Commands.add('addTaskApi', ({ title, boardIndex = 0, listIndex = 0 }) => {
cy.request('POST', '/api/tasks', {
title,
boardId: Cypress.env('boards')[boardIndex].id,
listId: Cypress.env('lists')[listIndex].id
})
.then(({ body }) => {
const tasks = Cypress.env('tasks') // tasks typed as any
// instead of 'tasks': Array<{ boardId:...number;
tasks.push(body);
})
})
我正在阅读这篇关于 Cypress 的 article。在最后一部分,作者在调用 Cypress.env
.
这是我想了解的片段。
export { };
declare global {
namespace Cypress {
export interface Cypress {
/**
* Returns all environment variables set with CYPRESS_ prefix or in "env" object in "cypress.json"
*
* @see https://on.cypress.io/env
*/
env(): Partial<EnvKeys>;
/**
* Returns specific environment variable or undefined
* @see https://on.cypress.io/env
* @example
* // cypress.json
* { "env": { "foo": "bar" } }
* Cypress.env("foo") // => bar
*/
env<T extends keyof EnvKeys>(key: T): EnvKeys[T];
/**
* Set value for a variable.
* Any value you change will be permanently changed for the remainder of your tests.
* @see https://on.cypress.io/env
* @example
* Cypress.env("host", "http://server.dev.local")
*/
env<T extends keyof EnvKeys>(key: T, value: EnvKeys[T]): void;
/**
* Set values for multiple variables at once. Values are merged with existing values.
* @see https://on.cypress.io/env
* @example
* Cypress.env({ host: "http://server.dev.local", foo: "foo" })
*/
env(object: Partial<EnvKeys>): void;
}
}
}
interface EnvKeys {
'boards': Array<{
created: string;
id: number;
name: string;
starred: boolean;
user: number;
}>;
'lists': Array<{
boardId: number
title: string
id: number
created: string
}>;
}
我在这段代码中有几个问题:
- typescript 如何知道这个名为
env.d.ts
的文件?我知道如果文件与文件同名,则打字稿会自动知道类型(例如command.ts
->command.d.ts
- 这里
export {}
有什么用。如果我评论这个,Vscode 抱怨。 - 为什么我们必须在这里添加
declare global
,而原始的 Cypress 打字稿以declare namespace Cypress
开头?
我不是打字专家,但这是我的看法
1.当它被命名为 env.d.ts
时,打字稿如何知道这个文件在tsconfig.json
你有
include": [
"**/*.ts"
]
这意味着 env.d.ts
包含在编译中。
运行 tsc --listFiles --noEmit
查看包含的内容。
2。这里的export {}有什么用
您正在合并命名空间,文档 Merging Namespaces 说
To merge the namespaces, type definitions from exported interfaces declared in each namespace are themselves merged.
进一步
Non-exported members are only visible in the original (un-merged) namespace. This means that after merging, merged members that came from other declarations cannot see non-exported members.
所以,它是信息隐藏 - 就像 public vs 私有变量。
糟糕,回答错误
我刚意识到你想知道第一行。
请看这个回答
I think the trick is just that an "external module" is a file containing an import or export statement, so this makes it an "external module".
3。为什么我们要加上 declare global
You can also add declarations to the global scope from inside a module
编写测试时,您可以使用 Cypress.Commands.add()
、cy.get()
、it()
等,无需导入任何内容,因为它们是全局声明的。
要与全局赛普拉斯界面合并,您的增强功能也必须声明为全局。
要看效果,改env.d.ts
declare module "env" {
namespace Cypress {
和addTaskApi.ts
Cypress.Commands.add('addTaskApi', ({ title, boardIndex = 0, listIndex = 0 }) => {
cy.request('POST', '/api/tasks', {
title,
boardId: Cypress.env('boards')[boardIndex].id,
listId: Cypress.env('lists')[listIndex].id
})
.then(({ body }) => {
const tasks = Cypress.env('tasks') // tasks typed as any
// instead of 'tasks': Array<{ boardId:...number;
tasks.push(body);
})
})