TypeScript 意外的类型Assert结果

dwbf0jvd  于 2022-10-29  发布在  TypeScript
关注(0)|答案(2)|浏览(255)

**类型脚本版本:**3.6.0-dev.20190801
搜索词:

generated/types.d.ts

export interface TypeD {
  da: string;
  db: string;
  dc: string;
}

export interface Test { 
  a: string;
  b: string;
  c: string;
  d?: { __private: 'd' } & TypeD;
}

src/index.model.ts(第一次)

import { Test } from 'generated/types';

type DType = NonNullable<Test['d']>;
export type Model = Pick<DType, keyof Exclude<DType, '__private'>>;

src/index.ts

import { Model } from './index.model';

export class A {
    value = <Model>{};
}

dist/index.model.d.ts的第一个字符串

import { Test } from 'generated/types';
declare type DType = NonNullable<Test['d']>;
export declare type Model = Pick<DType, keyof Exclude<DType, '__private'>>;
export {};

dist/index.d.ts(第一次)

export declare class A {
    value: Pick<{
        __private: "d";
    } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
}

预期行为:

我希望dist/index.d.ts类型定义会导致:

import { Model } from './index.model';
export declare class A {
    value: Model;
}

实际上,这是类型定义的结果,如果我将value = <Model>{};更改为value: Model = <Model>{};
为什么typescript在Assert类型时不直接使用Model

实际行为:

结果:

export declare class A {
    value: Pick<{
        __private: "d";
    } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
}

Playground链接:

我不知道如何在playroom中编译声明,对不起:(
作为替代方案,请克隆以下存储库:https://github.com/klemenoslaj/typescript-type-assertion

说明:

这在monorepo环境中是一个相当重要的问题。
发生的情况是,项目在dist/文件夹中编译,它们包含如上所述的相对路径(import("../generated/types")),该路径从src/指向,而不是从dist/指向,当项目开始使用另一个项目时,实际上会产生错误。
为什么不打印脚本:

  • 是否使用导入的原始路径(generated/types)?
  • 是否直接使用Assert中的类型(Model)?
k10s72fa

k10s72fa1#

类型别名的一般特性是编译器可以透明地扩展它们,因此当您使用Assert时,编译器可能认为它不需要保留名称。
使用界面可能会得到您想要的效果:

export interface Model extends  Pick<DType, keyof Exclude<DType, '__private'>> {}
hgb9j2n6

hgb9j2n62#

类型别名的一般特性是编译器可以透明地扩展它们,因此当您使用Assert时,编译器可能认为它不需要保留名称。
使用界面可能会得到您想要的效果:

export interface Model extends  Pick<DType, keyof Exclude<DType, '__private'>> {}

是的,可以👍
然而,我们不能强迫人们使用接口,因此问题可能仍然会突然出现,造成挫折,因为它不是真正直接的问题。
还有别的办法吗?

编辑

此外,如果类型是由第三方生成的,我们甚至会失去控制,直接使用generated/types中的类型也会导致同样的问题。
我已经相应地更新了存储库:

export class A {
    value1 = <Model>{};
    value2 = <Test['e']>{};
}

结果

export declare class A {
    value1: Pick<{
        __private: "d";
    } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
    value2: {
        __private: "e";
    } & import("../generated/types").TypeD;
}

相关问题