Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript: can't find built-in utility types if "noLib": true #106

Open
johhnry opened this issue Feb 17, 2023 · 6 comments
Open

TypeScript: can't find built-in utility types if "noLib": true #106

johhnry opened this issue Feb 17, 2023 · 6 comments

Comments

@johhnry
Copy link
Contributor

johhnry commented Feb 17, 2023

Hi,

Thanks for making those type definitions, this is really helpful to be able to use TypeScript for Adobe products!

This is a sample config for tsconfig.json and package.json:

// tsconfig.json
{
  "compilerOptions": {
    "module": "none",
    "noLib": true,
    "types": ["types-for-adobe/Photoshop/2015.5"],
    "strict": true,
    "target": "ES3",
    "downlevelIteration": true
  },
  "include": ["src/**/*"]
}
// package.json
{
  // ...
  "dependencies": {
    "types-for-adobe": "^7.0.12",
    "typescript": "^4.9.5"
  }
}

I found that this minimal example compiles but raise a TypeScript error during compilation:

// error TS2318: Cannot find global type 'Extract'.
function fn<T>(object: T) {
  for (const key in object) {}
}

// Note that this works:
function fn(object: any) {
  for (const key in object) {}
}

I don't know the internals of how the for ... in gets compiled using generics but it made me realize that I can't use any of the utility types when using "noLib": true in tsconfig.json:

// error TS2304: Cannot find name 'Extract'.
type T0 = Extract<"a" | "b" | "c", "a" | "f">;

This is because utility types are located in lib.es5.d.ts therefore not included with noLib.

I can still copy the Extract type definition in my project but maybe we can include them in the repository?

// Compiles fine
type Extract<T, U> = T extends U ? T : never;

function fn<T>(object: T) {
  for (const key in object) {}
}

Thanks!

@YoungQi9754
Copy link

I also encountered this problem,
then I tried removing noLib:true and adding ["ES5", "ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020", "ES2021", "ESNext"] in lib, manually removing dependencies on lib.dom, but keeping lib.es*, you can try this and see if it helps you. That would be the best outcome if it works for you.

@YoungQi9754
Copy link

{
  "compilerOptions": {
    "lib": [
      "ES5",
      "ES2015",
      "ES2016",
      "ES2017",
      "ES2018",
      "ES2019",
      "ES2020",
      "ES2021",
      "ESNext"
    ]
  }
}

@YoungQi9754
Copy link

I guess the reason is the 'noLib:true' setting in the tsconfig.json file of the declaration file. This setting can exclude the default dependency of lib.dom, because Document is overridden in the .d.ts file. By excluding lib.dom, there won't be any errors when writing declarations. However, after setting this, 'noLib:true' must also be set in the tsconfig.json of your own project, or you need to manually exclude lib.dom.

This is my own understanding. If there is an official response, please let me know if I am right or wrong, or suggest a better way to set it up.

Thank you.

@johhnry
Copy link
Contributor Author

johhnry commented Mar 1, 2023

I also encountered this problem, then I tried removing noLib:true and adding ["ES5", "ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020", "ES2021", "ESNext"] in lib, manually removing dependencies on lib.dom, but keeping lib.es*, you can try this and see if it helps you. That would be the best outcome if it works for you.

The issue with adding those to the lib array is that the declarations conflict with the ones provided by types-for-adobe, typically:

node_modules/types-for-adobe/shared/JavaScript.d.ts:4:1 - error TS6200: Definitions of the following identifiers conflict with those in another file: Object, Array, Math, Date, Function, String, Number, Boolean, RegExp, Error, Partial, Readonly, Pick, Record

@utenma
Copy link

utenma commented Apr 24, 2023

you can safely add the following from lib.es5.d.ts into a typescript.d.ts

type ArrayLike<T> = {
  readonly length: number;
  readonly [n: number]: T;
}

/**
* Make all properties in T optional
*/
type Partial<T> = {
  [P in keyof T]?: T[P];
};

/**
* Make all properties in T required
*/
type Required<T> = {
  [P in keyof T]-?: T[P];
};

/**
* Make all properties in T readonly
*/
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
  [P in K]: T;
};

/**
* Exclude from T those types that are assignable to U
*/
type Exclude<T, U> = T extends U ? never : T;

/**
* Extract from T those types that are assignable to U
*/
type Extract<T, U> = T extends U ? T : never;

/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

/**
* Exclude null and undefined from T
*/
type NonNullable<T> = T & {};

/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;

/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;

@johhnry
Copy link
Contributor Author

johhnry commented Apr 24, 2023

@mindlid Yes sure! Or only copy the ones you need in your project (like Extract above) ^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants