tsconfig和环境声明中的项目引用

时间:2018-11-29 16:30:53

标签: typescript build dependencies tsconfig

我正在尝试将Typescript项目配置为具有以下目录结构:

src/
├── client/
│   └── tsconfig.json
│
├── server/
│   └── tsconfig.json
│
├── shared/
│   ├── utils/
│   │   └── type-utils.d.ts
│   │
│   └── tsconfig.json
│
└── tsconfig-base.json
  • client/tsconfig.jsonserver/tsconfig.jsonshared/tsconfig.json分别具有"extends": "../tsconfig-base.json"

  • client/tsconfig.jsonserver/tsconfig.json都具有"references": [{ "path": "../shared" }]

  • shared/utils/type-utils.d.ts不是模块,而是包含环境类型声明,例如IdCouldBeNull,以及Array的声明合并(定义flatMap方法。

这样的想法是tsconfig-base.json可以包含很多通用设置,单个tsconfig.json可以定义与该子项目相关的设置(例如,React for client/tsconfig.json,Node for { {1}}和server/tsconfig.json将在shared/client/之间共享。

问题在于,server/shared/utils/type-utils.ts看不到环境声明和声明合并client/,而server/则看不到。这会导致错误,例如shared/产生

tsc -b client --verbose

隐式$ tsc -b client --verbose 15:31:41 - Projects in this build: * shared/tsconfig.json * client/tsconfig.json 15:31:41 - Project 'shared/tsconfig.json' is up to date because newest input 'shared/formatting/numbers.ts' is older than oldest output 'shared/formatting/numbers.js.map' 15:31:41 - Project 'client/tsconfig.json' is out of date because output file 'client/client/index.js' does not exist 15:31:41 - Building project 'C:/Users/KRyan/Web/5heet/client/tsconfig.json'... client/index.tsx(32,29): error TS7006: Parameter 'skill' implicitly has an 'any' type. client/index.tsx(80,37): error TS2339: Property 'flatMap' does not exist on type 'Ability[]'. client/index.tsx(80,45): error TS7006: Parameter 'ability' implicitly has an 'any' type. client/index.tsx(88,16): error TS7006: Parameter 'one' implicitly has an 'any' type. client/index.tsx(88,21): error TS7006: Parameter 'another' implicitly has an 'any' type. client/index.tsx(151,32): error TS7031: Binding element 'id' implicitly has an 'any' type. client/parts/editing.tsx(31,60): error TS2339: Property 'oneOperand' does not exist on type 'never'. client/parts/editing.tsx(31,81): error TS2339: Property 'operator' does not exist on type 'never'. client/parts/editing.tsx(31,108): error TS2339: Property 'anotherOperand' does not exist on type 'never'. client/parts/portal.tsx(55,61): error TS2304: Cannot find name 'Omit'. shared/ability.d.ts(2,33): error TS2304: Cannot find name 'Id'. shared/ability.d.ts(8,36): error TS2304: Cannot find name 'Id'. shared/ability.d.ts(12,37): error TS2304: Cannot find name 'Id'. shared/character.d.ts(3,35): error TS2304: Cannot find name 'Id'. shared/expression.d.ts(7,35): error TS2304: Cannot find name 'Id'. shared/expression.d.ts(30,38): error TS2304: Cannot find name 'ElementOf'. shared/expression.d.ts(33,118): error TS2304: Cannot find name 'Id'. shared/formatting/numbers.d.ts(1,41): error TS2304: Cannot find name 'Id'. shared/skill.d.ts(3,31): error TS2304: Cannot find name 'Id'. shared/utils/basic.d.ts(5,46): error TS2304: Cannot find name 'CouldBeNull'. 类型是由于无法找到输出后半部分列出的各种名称而直接导致的。

出于完整性考虑,完整文件:

any

shared/utils/type-utils.d.ts

type PropsOf<T> = T[keyof T]; type ElementOf<T> = T extends (infer E)[] ? E : T; type Subtract<T, U> = Pick<T, Exclude<keyof T, keyof U>>; type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; type CouldBeNull<T> = null extends T ? unknown : never; type DeepPartial<T> = { [P in keyof T]?: T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : DeepPartial<T[P]> }; declare class Tagged<Tag> { private 'is tagged as': [Tag]; private dummy(): Tag; } type Id<Tag> = string & Tagged<Tag>; interface Array<T> { /** * Calls a defined callback function on each element of an array. Then, flattens the result into * a new array. * This is identical to a map followed by a flatten of depth 1. * * @param callback A function that accepts up to three arguments. The flatMap method calls the * callback function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callback function. If * thisArg is omitted, undefined is used as the this value. */ flatMap<U, This = undefined>( callback: (this: This, value: T, index: number, array: T[]) => U | U[], thisArg?: This, ): U[]; }

tsconfig-base.json

{ "compileOnSave": true, "compilerOptions": { "target": "es2018", "baseUrl": ".", "module": "amd", "moduleResolution": "classic", "paths": { "csstype": [ "node_modules/csstype/index" ], }, "composite": true, "declaration": true, "declarationMap": true, "noEmitOnError": true, "strictNullChecks": true, "allowJs": false, "allowUnusedLabels": false, "noImplicitAny": true, "noImplicitThis": true, "noImplicitReturns": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noStrictGenericChecks": true, "noUnusedLocals": true, "noErrorTruncation": true, "allowUnreachableCode": false, "forceConsistentCasingInFileNames": false, "preserveConstEnums": true, "sourceMap": true } }

client/tsconfig.json

{ "extends": "../tsconfig-base.json", "include": [ "**/*.ts" ], "outDir": "../../built/client", "compilerOptions": { "rootDir": "..", "jsx": "react", "types": [ "react", "react-dom" ] }, "references": [ { "path": "../shared" } ], "watch": true }

server/tsconfig.json

{ "extends": "../tsconfig-base.json", "include": [ "**/*.ts" ], "outDir": "../../built/server", "compilerOptions": { "rootDir": "..", "module": "commonjs", "types": [ "node", "mime-types" ] }, "references": [ { "path": "../shared" } ] }

shared/tsconfig.json

1 个答案:

答案 0 :(得分:0)

想出了 a 解决方案,尽管我对此并不感到困惑:

client/tsconfig.json

{
    "extends": "../tsconfig-base.json",
    "include": [
        "**/*.ts",
        "**/*.tsx",
        "../shared/utils/type-utils.d.ts"
    ],
    "outDir": "../built/client",
    "compilerOptions": {
        "baseUrl": "..",
        "rootDir": "..",
        "jsx": "react",
        "types": [
            "react",
            "react-dom"
        ]
    },
    "references": [
        {
            "path": "../shared"
        }
    ],
    "watch": true
}

请注意../shared/utils/type-utils.d.ts部分中的include。这样就解决了问题。

我对这种解决方案并不陌生,因为它意味着在shared/中明确列出某些内容,而不是作为项目参考的结果而将其包括在内。我对于必须为要添加tsconfig.json的每个新.d.ts文件必须手动更新shared/的想法感到不满意。但这是 的答案,因为该项目可以构建,而且我并不是很可能 向该项目添加更多自己的.d.ts文件,因此我对此项目的关注可能是哲学/理论上的。