정의 파일의 클래스 가져오기(*d.ts)
세션 저장소에서 사용자 지정 데이터를 사용할 수 있도록 Express Session 타이핑을 확장하고 싶습니다.는 목적이 .req.session.user입니다.User:
export class User {
public login: string;
public hashedPassword: string;
constructor(login?: string, password?: string) {
this.login = login || "" ;
this.hashedPassword = password ? UserHelper.hashPassword(password) : "";
}
}
나는 의 ★★★★★★★★★★★★★★★★★★★★★★★★★★★를 만들었다.own.d.ts정의를 기존 익스프레스 세션 유형과 병합하는 파일:
import { User } from "./models/user";
declare module Express {
export interface Session {
user: User;
}
}
하지만 전혀 작동하지 않습니다 - VS Code와 TSC는 그것을 인식하지 않습니다.그래서 간단한 유형으로 테스트 정의를 만들었습니다.
declare module Express {
export interface Session {
test: string;
}
}
그리고 test field는 정상적으로 동작하고 있기 때문에, Import의 원인에는 문제가 있습니다.
도 '아예'를 했어요./// <reference path='models/user.ts'/>대신 Import했지만 TSC에 User 클래스가 표시되지 않았습니다.*d.ts 파일에서 내 클래스를 사용하려면 어떻게 해야 합니까?
편집: 컴파일 시 정의 파일을 생성하도록 tsc를 설정했더니 user.d.ts:
export declare class User {
login: string;
hashedPassword: string;
constructor();
constructor(login: string, password: string);
}
Express Session 확장용 자체 타이핑 파일:
import { User } from "./models/user";
declare module Express {
export interface Session {
user: User;
uuid: string;
}
}
그러나 import 명세서가 위에 있을 때는 여전히 작동하지 않습니다.좋은 생각 있어요?
2년간의 TypeScript 개발 끝에 드디어 이 문제를 해결할 수 있었습니다.
기본적으로 TypeScript에는 "로컬"(일반 모듈)과 "환경"(글로벌)의 두 가지 모듈 유형 선언이 있습니다.두 번째 종류에서는 기존 모듈 선언과 병합된 글로벌모듈 선언을 쓸 수 있습니다.이 파일의 차이점은 무엇입니까?
d.ts파일은 Import가 없는 경우에만 주변 모듈 선언으로 취급됩니다.Import 행을 지정하면 글로벌이 아닌 일반 모듈파일로 처리되므로 모듈 정의를 증강할 수 없습니다.
그래서 여기서 설명한 모든 솔루션이 작동하지 않습니다. 다행히2. 2.9를 사용하여 수 .import()★★★★
declare namespace Express {
interface Request {
user: import("./user").User;
}
}
이 행은import("./user").User;이 작동하게 되었습니다 : ) does does does does does does does does::::::::::::::::::)
마이카우 리텍의 답변 덕분입니다여기 제가 프로젝트에서 사용한 다른 방법이 있습니다.
수입할 수 .User쓰기 없이 여러 번 재사용할 수 있습니다.import("./user").User구현하거나 재수출할 수도 있습니다.
declare namespace Express {
type User = import('./user').User;
export interface Request {
user: User;
target: User;
friend: User;
}
export class SuperUser implements User {
superPower: string;
}
export { User as ExpressUser }
}
즐거운 시간 보내세요:)
완전성을 위해:
- 앰비언트 모듈 선언이 있는 경우(즉, 최상위 Import/export가 없는 경우)에는 명시적으로 Import할 필요 없이 글로벌하게 사용할 수 있지만 모듈 선언이 있는 경우 컨슈머 파일에 Import해야 합니다.
- 주변 모듈 선언에서 기존 유형(다른 파일에서 내보내기)을 가져오려면 최상위 수준 가져오기로는 가져올 수 없습니다(이 경우 주변 선언으로 남아 있지 않기 때문입니다).
이렇게 하면 (https://stackoverflow.com/a/39132319/2054671))
// index.d.ts
import { User } from "./models/user";
declare module 'express' {
interface Session {
user: User;
uuid: string;
}
}
이 새로운 인터페이스로 기존 '오브젝트' 모듈을 증강합니다.https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
단, 이 기능을 사용하려면 컨슈머 파일에 Import해야 합니다.더 이상 앰비언트 선언이 아니기 때문에 앰비언트 선언과 같이 기본적으로는 글로벌하게 사용할 수 없습니다.
다른 .
declare예에 대해 하지 않은 으로 Import할 수 .)block ( Import하다)이렇게 하려면 이와 같은 일반 가져오기를 사용할 수 없습니다.
declare module B { import A from '../A' const a: A; }현재 실장에서는 Import된 모듈의 해결 규칙이 혼란스러워서 ts에서는 이를 허용하지 않기 때문입니다.입니다.
Import or export declaration in an ambient module declaration cannot reference module through relative module name.(해당 github 문제에 대한 링크를 찾을 수 없습니다.누군가 발견하면 이 답변을 수정하여 언급해 주십시오.https://github.com/microsoft/TypeScript/issues/1720)다음과 같은 작업을 수행할 수 있습니다.
declare module B { import React from 'react'; const a: A; }이는 절대 경로 Import이며 상대 경로 Import가 아니기 때문입니다.
따라서 앰비언트모듈에서 이를 올바르게 수행하려면 다이내믹 Import 구문(https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#import-types)을 사용하는 방법밖에 없습니다.
declare namespace Express { interface Request { user: import("./user").User; } }접수된 답변에 기재된 바와 같이 (https://stackoverflow.com/a/51114250/2054671))
다음과 같은 방법으로 글로벌 확장을 수행할 수도 있습니다.
import express = require('express'); import { User } from "../models/user"; declare global { namespace Express { interface Session { user: User; uuid: string; } } }단, 글로벌 증대는 주변 선언이 아닌 모듈에서만 가능하므로 @masa의 답변(https://stackoverflow.com/a/55721549/2054671)에서 설명한 바와 같이 컨슈머 파일에 Import할 경우에만 작동합니다.
위의 모든 사항은 주변 모듈 내의 다른 곳에서 내보내는 모듈을 Import할 때 유효하지만 다른 주변 모듈로 주변 모듈을 Import하는 것은 어떻습니까?(이것은, 기존의 앰비언트 모듈을 사용해, 앰비언트 모듈의 전기 소비 장치에서도 그러한 앰비언트 타입이 보이는 것을 확인하는 경우에 도움이 됩니다.
를 사용할 수 있습니다.
/// <reference types="../../a" />지시의// ambientA.d.ts interface A { t: string }// ambientB.d.ts /// <reference types="../ambientA.d.ts" /> declare module B { const a: A; export { a }; }
기타 관련 답변 링크:
갱신하다
typescript 2.9부터 글로벌모듈로 type을 Import할 수 있을 것 같습니다.자세한 내용은 승인된 답변을 참조하십시오.
원래의 회답
당신이 직면하고 있는 문제는 클래스 타이핑보다는 모듈 선언을 늘리는 것이라고 생각합니다.
컴파일을 시도하면 알 수 있듯이 내보내기는 문제 없습니다.
// app.ts
import { User } from '../models/user'
let theUser = new User('theLogin', 'thePassword')
모듈 선언을 확대하려고 하는 것 같습니다.Express그리고 당신은 정말 친합니다.이렇게 하면 효과가 있습니다.
// index.d.ts
import { User } from "./models/user";
declare module 'express' {
interface Session {
user: User;
uuid: string;
}
}
단, 이 코드의 정확성은 물론 express declaration 파일의 최초 구현에 따라 달라집니다.
이 논리를 따르는 것 만으로는 불가능한가?express-session:
own.d.ts:
import express = require('express');
import { User } from "../models/user";
declare global {
namespace Express {
interface Session {
user: User;
uuid: string;
}
}
}
대체로index.ts:
import express from 'express';
import session from 'express-session';
import own from './types/own';
const app = express();
app.get('/', (req, res) => {
let username = req!.session!.user.login;
});
적어도 이것은 문제없이 컴파일 되는 것 같다.완전한 코드에 대해서는, https://github.com/masa67/so39040108 를 참조해 주세요.
여기를 봐주세요.
https://stackoverflow.com/a/43688680/5412249
모듈의 유형(즉, Import/export를 사용하는 파일)을 선언하고 이러한 유형을 글로벌 네임스페이스로 증강(머지)할 수 있습니다.
중요한 것은 타입 정의를 내부로 삽입하는 것입니다.
declare global { ... }
다음은 Cypress 사용자에게 익숙한 예입니다.
// begin file: custom_command_login.ts
import { foo } from './utils';
Cypress.Commands.add('logIn', () => {
// ...
});
// add custom command to Cypress namespace
// so that intellisense will correctly show the new command
// cy.logIn
declare global {
namespace Cypress {
interface Chainable {
logIn();
}
}
}
// end file: custom_command_login.ts
언급URL : https://stackoverflow.com/questions/39040108/import-class-in-definition-file-d-ts
'programing' 카테고리의 다른 글
| angularjs는 ng-module로 동작하지 않는 필수 항목을 선택합니다. (0) | 2023.04.05 |
|---|---|
| 관계형 데이터베이스 대신 NoSQL 데이터베이스를 사용해야 하는 경우둘 다 같은 사이트에서 사용해도 될까요? (0) | 2023.04.05 |
| Formik의 setError 메서드를 올바르게 사용하는 방법(리액트 라이브러리) (0) | 2023.03.31 |
| 로그에 WARN 메시지를 기록하지 않는 Spring @ExceptionHandler 메서드를 작성하려면 어떻게 해야 합니까? (0) | 2023.03.31 |
| JSON에 적합한 CLI 툴은 무엇입니까? (0) | 2023.03.31 |