-
Notifications
You must be signed in to change notification settings - Fork 0
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
Provide standard types #1
Comments
I like it. We can also publish to |
I'm not 100% convinced on the value of the namespace though, so I'd love more input. Otherwise we can just establish a NPM package name pattern that we follow. E.g. |
👍 on publishing non-npm to |
Ok, thats a good idea. Since you would be expected to explicitly require the interfaces, there's no need to use typeroots for this. Importing from import {PackageJson} from "@typings/package-json";
export function generatePackage(): PackageJson {
// ...
} (About names, I am not sure if we should add "schema" in the name, I feel that it sounds as if we also bundled a runtime function to test if an object matches an interface (schema validator), but I may be wrong) |
I don't really see the value in such type aliases.
vs Going down the road of defining different type aliases for the possible values that are not actually the same type it's unclear where to draw the line. Do you want an alias for If you want real type safety, define a class that represents the path, like the WHATWG Re: |
The scope is about organization management. So that tools can be created to automate things. Also, usage of it would be: import '@typings/abc'
Abc.Xyz... I agree that |
It must depend on the editor. I am using Webstorm and it does not do full resolution. Here is what I get: I can even click on "PosixPath" to get a description: If I remember well enough, Typedoc does not do full resolution but links to aliases (like Webstorm) so you would get the same benefits (explained type alias semantics). About adding further distinctions (relative, absolute), I'd say that drawing this line is the role of the maintainer, to decide what's the reasonable point to stop. For a general-purpose library, I see the point for Here are some real examples where type aliases (and quick doc) helped me.
I could use a Time class abstracting this and handling unit conversions, but at the end of the day I would still need to call this external function requiring a number, so do I use This is already a long message, but I still hear your point: the compiler does not help you there. I know, but there are some open issues to provide similar features: Tagged types, Units. Each compiler has its limits, I really love Typescript but sometimes you have to admit that you cannot express something and enforce it with the compiler, so type aliases are a best-effort idea to bridge the gap until tagged types are implemented. There also was some proposition to reintroduce small bits of nominal typings. It may be a bit extreme but having nominally typed aliases would allow you to do rewrite the // Current node.d.ts
interface posix {
export function join(...paths: any[]): string;
export function resolve(...pathSegments: any[]): string;
// ...
}
// Using nominally typed aliases:
interface posix {
export type Path<S extends string = string> = S; // A `Path` is a subset of `string`
export type AbsPath<P extends Path = Path> = P; // An `AbsPath` is a subset of `Path`
export function join(path: AbsPath, ...paths: Path[]): AbsPath;
export function join(...paths: Path[]): Path;
export function resolve(...pathSegments: Path[]): AbsPath;
// ...
}
// Then I would go as far as requiring compile-time checks
const foo: posix.Path = "test/tsconfig.json";
const bar: string = "package.json";
// Ok
const resolvedFoo: posix.AbsPath = posix.resolve(foo); // Ok
// Ok, but compilation error if `as posix.Path` is missing
const resolvedBar: posix.AbsPath = posix.resolve(bar as posix.Path); The last example may be a bit too disruptive for the ecosystem right now, but I'd like to tend in this direction were types can encode additional predicates. Ok, so this was a long answer to explain my point of view on aliases. Should I open a separate issue? About |
It's not just about namespace. It's about tooling and avoid confusion. I would prefer the system to be generic and no special case handling. The example I gave should really be But the idea is the same. Those would be non-npm libraries and they are all global/script |
@demurgos than I assume Webstorm doesn't use the official TS language service, which is what we should optimise for. @unional re: namespace, I prefer something like |
@felixfbecker completely agree. I prefer |
For tooling, I mean microsoft/types-publisher#4 (comment) |
Just created https://github.com/global-types |
I'd prefer not to have these be global types though. The issue with globals is that they conflict and are abstract. Especially with NPM flattening, we can run into duplicate identifiers. I'd prefer to keep importing the types like Edit: The name itself doesn't matter too much. Like I mentioned, we can also just publish these as regular packages today like |
We can name it anything we want. I assume we are referring to non-npm library. In those cases, how do JS use them? My assumption is that they are global. ...oh, things like In the past, I have created organizations like |
@felixfbecker You may be right that optimizing for the official compiler is the right thing to do. I always used Webstorm so wasn't aware of the difference. Regarding the comparison with normal documentation, I guess that it's a matter of personal preference. It's not only about function arguments but also with local variables, since I type most of my variables, having an alias allows me to better express my assumptions about a variable. As stated in the original comment, it also allows me to provide a single detailed description of what an alias means, so I can focus my function documentation on the role of the parameters instead of their "shape". @unional Sure, go ahead: you can invite me. Regarding the imports, I also prefer the standard ES syntax. The Typescript references always seemed to me like an implementation detail introduced when TS did not follow the Node's resolution algorithm. Just to be sure, I assume that any of those types will be local and will have to be manually imported by any module relying on it. Different versions in different parts of the dependency tree should not clash. They are "global types" because they are useful for the whole ecosystem, not because they introduce globals. |
@unional Could you link to this "bower-types" organization? I couldn't find it, does it still exists? Regarding the name, I fear that "global-types" sounds to much as if it extended the environment by adding only global types. Beyond the increased risk of conflict caused by globals, it's also harder to trace were the definitions comes from. Do you add I like @felixfbecker's |
I have deleted it. ES imports implies more as you are importing actual code instead of just types. I am neutral on either way. Personally I also don't use |
I'm closing this issue because it's stale. There's interest around having more types but it's better to work on them individually. Types for JSON files would be better served by repositories with dedicated schemas, providing both TS types and various runtime check helpers. What I called semantic types may be interesting but the only way to use them reliably for interop would be to have them as nominal/branded/tagged types inside tslib. I still think that Node's typing should be broken down and refactored, but it requires a massive effort because they are so relied upon. Utility types are already numerous in the standard lib. Additional types can just be exposed as individual |
Hi,
This post is a suggestion to add general purpose types that others can rely on.
I would like to increase the number of
lib-*
types and other such type definitions that are not tied to a single library. Currently there are only two "lib" repositories: lib-json-schema and lib-http-status-codes. We could do more. There are many occasions when I need a type that is not tied to a library. I often end up writing my own ad-hoc definitions but having a standardized representations would help. I believe that this organization is the best place to host them.Here are some concrete examples.
package.json
,tsconfig.json
We could provide interfaces for popular JSON files. Typescript exposes definitions for parsed compiler options but not for "tsconfig.json" files. While writing build tools, being able to have a typed
package.json
would also help. We could also provide a genericJson
type (more restrictive thanany
), types for web extension manifests, bower files, etc.In addition to providing type information, it could also leverage doc comments to provide quick documentation.
Semantic types
This is mostly about providing aliases for primitive types to hint the usage, even if the compiler does not use it. Concretely, I often like to type my functions this way:
Typescript sees it as
readFirstByte(path: string): number
but as a developer, displaying the arguments or jumping to the declaration allows me to quickly understand that it's not any string but a POSIX path.We could provide a library with commented aliases explaining the semantics of each alias to facilitate documentation purposes. Instead of repeating the description of an
Uint8
I could generate documentation to link to the "canonical" description. Given the huge variety of string types, it could be nice to agree on some relation between a name and definition that can be used across the ecosystem.Here are some example for strings:
JsonString
,Hex
,Uuid
,Host
,MediaType
,Cidr
,CssColor
,ClassName
,Uri
,SysPath
,WinPath
,PosixPath
...Node components
Node has a big API. If you need the types for only part of the API (for example streams or event emitters), you have to pull the whole definitions. It means that you create globals when in fact you may only want the event emitter types to expose a compatible implementation (for example for browsers). We could try to modularize the Node definitions, and eventually turn the Node definitions into a simple aggregation of smaller type definitions.
Utility types
I am not sure if those are still needed now that the standard lib comes bundled with many utility types. But we could have a package providing types of the same sort as
Partial<T>
orMapLike<T>
. I no longer really rely on this sort of helper types so I am not sure if it's really needed but it's an idea.What do you think about it? If such "general-purpose" types are created, how should they be published? They don't really belong to
@types
since they are not attached to a single library. They would fit nicely withtypings
but its deprecated. We could simply publish those as standalone npm packages using the oldtyped-
prefix. (typed-package.json
for example).The text was updated successfully, but these errors were encountered: