-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[Feature request] allow use as const
+ type
or interface
#31062
Comments
I can't really tell what you're trying to do with this |
when miss and at end, it will out like normal
|
@bluelovers interface IVueCliPrompt
{
name: string,
type: 'confirm' | string,
message: string,
default: unknown
} Instead of writing explicitly ReadonlyArray<Readonly>: const prompts: ReadonlyArray<Readonly<IVueCliPrompt>> = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
]; You want 'as const Type' to behave as the 'Type' was written in the left side. const prompts = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
] as const VueCliPrompt[]; // Same effect as previous code sample Correct ? |
im not wanna do a
and output code like we do do type check like as
.ts interface IVueCliPrompt
{
name: string,
type: 'confirm' | string,
message: string,
default: unknown
}
const prompts: IVueCliPrompt[] = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
{
name: 'replaceFiles2',
type: 'confirm',
message: 'Replace current files with preset files?',
},
];
export = prompts but output declaration (.d.ts) like
.ts const prompts = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
] as const; => .d.ts declare const prompts: readonly [{
readonly name: "replaceFiles";
readonly type: "confirm";
readonly message: "Replace current files with preset files?";
readonly default: false;
}];
export = prompts; at endinterface IVueCliPrompt
{
name: string,
type: 'confirm' | string,
message: string,
default: unknown
}
const prompts = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
{
name: 'replaceFiles2',
type: 'confirm',
message: 'Replace current files with preset files?',
// error here => Error:(20, 2) TS2741: Property 'default' is missing in type '{ name: string; type: string; message: string; }' but required in type 'IVueCliPrompt'.
},
] as const IVueCliPrompt[];
export = prompts =>
interface IVueCliPrompt
{
name: string,
type: 'confirm' | string,
message: string,
default: unknown
}
const prompts = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
{
name: 'replaceFiles2',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
] as const IVueCliPrompt[];
export = prompts => .d.ts declare const prompts: readonly [{
readonly name: "replaceFiles";
readonly type: "confirm";
readonly message: "Replace current files with preset files?";
readonly default: false;
}, {
readonly name: 'replaceFiles2',
readonly type: 'confirm',
readonly message: 'Replace current files with preset files?',
readonly default: false
},];
export = prompts; |
I believe he wants to use the
|
@Gregroam yes |
But that's a type assertion, not check. Wouldn't it be closer to
|
a bug? here
interface IVueCliPrompt
{
name: string,
type: 'confirm' | string,
message: string,
default: unknown
}
const prompts: IVueCliPrompt = [
{
name: 'replaceFiles',
type: 'confirm',
message: 'Replace current files with preset files?',
default: false
},
{
name: 'deps-cross-fetch',
type: 'confirm',
message: 'Add cross-fetch?',
default: false
},
] as const;
export = prompts |
This StackOverflow question can be solved with this, |
Anything mew about this feature? Will really help defining const literals with typed structure |
All of our planning documents are public; please don't ping for news or mews. |
Unfortunately, this doesn't work as expected. const foo2 = {} as const
const foo3 = {
b: 'property "a" is missing in this object'
} as const;
const foo4 = {
newProperty: '122',
} as const;
const foo5 = {
newProperty: '122',
};
<ITest>foo2; // doesn't throw an error
<ITest>foo3; // doesn't throw an error
<ITest>foo4; // does throw an error: Conversion of type '{ readonly newProperty: "122"; }' to type 'ITest' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type '{ readonly newProperty: "122"; }' is missing the following properties from type 'ITest': a, b
<ITest>foo5; // does throw an error: Conversion of type '{ newProperty: string; }' to type 'ITest' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type '{ newProperty: string; }' is missing the following properties from type 'ITest': a, b
There was no solution proposed using only the type system. They both need defining a variable (or a function) that is useless during runtime. |
I have a use-case where I think this would be helpful. Our Schema module (WIP: https://developer.spruce.ai/#/schemas/index) is built to standardize data structures/models across our ecosystem. Our CLI tool generates types/interfaces/protocols for different languages based on these definitions. Because we write our definitions in typescript, it would be so cool if we didn't have to rely on generated files to create types based on those definitions. Here is a snippet pulled and modified from one of our tests that I can't get to work because the widening that happens: //buildSchemaDefinition= <T extends ISchemaDefinition>(definition: T) => definition
const userDefinition = buildSchemaDefinition({
id: 'select-union-test',
name: 'select union test',
fields: {
name: { type: FieldType.Text },
favoriteColor: {
type: FieldType.Select,
options: {
choices: [
{
value: 'blue',
label: 'Blue'
},
{
value: 'red',
label: 'Red'
}
]
}
}
}
})
type SelectUnion = 'blue' | 'red'
const user = new Schema(userDefinition, { favoriteColor: 'blue' })
// favorite colors should be a union of all choices[number]['value'], so should match SelectUnion
// instead it's widened to a string (allowing favoriteColor to be set to anything without warning)
const favColor: SelectUnion = user.get('favoriteColor')
t.is(favColor, 'blue') I tried doing putting const userDefinition = buildSchemaDefinition<{.... definition ...}>({... definition a second time ...})
// now there is no widening, so I can map it really helpful ways
const user : SchemaDefinitionValues<typeof userDefinition> = {
name: 'Tay',
favoriteColor: 'wrong' // not one of 'blue' | 'red'
} Now I can import the definitions and work in them in real time and have my "value objects" check themselves (so changing the choices of a universal definition of a person in our platform will immediately fail lint). The type mapping is here: https://github.com/sprucelabsai/spruce-schema/blob/dev/src/Schema.ts#L52 Thanks! |
I wonder if #32758 would end up solving this, or maybe this would have to be solved in order to get that issue done. |
I also see a big need for this feature. To add to the reasoning:
My idea on how to make this work is just to mimic the const myPets = [{...}, {...}, ...] as Const<Pet[]>;
const myPets: Const<Pet[]> = [{...}, {...}, ...];
// or
const myPets = [{...}, {...}, ...] as Literal<Pet[]>;
const myPets: Literal<Pet[]> = [{...}, {...}, ...]; |
i think new https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-beta/#the-satisfies-operator |
I disagree. It's a step in the right direction, but if you add
So the type will be checked, but the resulting type is still widened up to the primitives instead of being literals. |
I filed #51173 as a bug against the |
Search Terms
Suggestion
Use Cases
allow use
as const
+type
orinterface
so we can make sure
as const
is followtype
orinterface
Examples
check
as const
output is followIVueCliPrompt[]
.ts
.d.ts
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: