Skip to content

Instantly share code, notes, and snippets.

@Narazaka
Created October 8, 2019 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Narazaka/3a4267d07688539f48808e32dd8de601 to your computer and use it in GitHub Desktop.
Save Narazaka/3a4267d07688539f48808e32dd8de601 to your computer and use it in GitHub Desktop.
const productAnalyticsPreset = {
id: 'number',
name: 'string',
start_at: 'string',
end_at: 'string',
name2: ['number', 'string'],
items: ['array', {
id: 'number',
name: ['string', 'undefined'],
it: {
f: 'boolean',
fa: ['array', 'boolean'],
f2a: ['array', ['boolean', 'string']],
g: ['array', []]
},
}],
foo: [['array', {
bar: 'string',
}], 'undefined'],
} as const;
export interface ScalarTypeMap {
number: number;
string: string;
symbol: symbol;
boolean: boolean;
undefined: undefined;
null: null;
}
export type ScalarTypeDefinition = keyof ScalarTypeMap;
export type ScalarTypeDefinitionToType<T extends ScalarTypeDefinition> = ScalarTypeMap[T];
export type TypesDefinition = ScalarTypeDefinition | readonly ScalarTypeDefinition[];
export type TypesDefinitionToType<T extends TypesDefinition> =
T extends ScalarTypeDefinition ? ScalarTypeDefinitionToType<T> :
T extends ReadonlyArray<infer U> ? U extends ScalarTypeDefinition ? ScalarTypeDefinitionToType<U> : never :
never;
export type ObjectTypeDefinition = {
readonly [key: string]: AllStructTypeDefinitions;
};
export type ObjectTypeDefinitionToType<T extends ObjectTypeDefinition> = {
[K in keyof T]: AllStructTypeDefinitionsToType<T[K]>;
};
export type ArrayTypeDefinition = readonly ['array', AllStructTypeDefinitions];
export type ArrayTypeToType<T extends ArrayTypeDefinition> =
T extends readonly ['array', infer U] ? U extends AllStructTypeDefinitions ? AllStructTypeDefinitionsToType<U> : never : never;
export type AllStructTypeDefinition = ScalarTypeDefinition | ObjectTypeDefinition | ArrayTypeDefinition;
export type AllStructTypeDefinitionToType<T extends AllStructTypeDefinition> =
T extends ScalarTypeDefinition ? ScalarTypeDefinitionToType<T> :
T extends ['array', any] ? ArrayTypeToType<T> :
T extends {} ? ObjectTypeDefinitionToType<T> :
never;
// interface AllStructTypeDefinitionToTypeSub<T extends AllStructTypeDefinition> extends AllStructTypeDefinitionToType<T> {}
export type AllStructTypeDefinitions = AllStructTypeDefinition | readonly AllStructTypeDefinition[];
export type AllStructTypeDefinitionsToType<T extends AllStructTypeDefinitions> =
T extends AllStructTypeDefinition ? AllStructTypeDefinitionToType<T> :
T extends ReadonlyArray<infer U> ? U extends AllStructTypeDefinition ? AllStructTypeDefinitionToType<U> : never : never;
// interface ArrayTypeToTypeSub<T extends ArrayTypeDefinition> extends ArrayTypeToType<T> {}
export type InterfaceDefinitionToType<T extends ObjectTypeDefinition> = {
[K in keyof T]:
T[K] extends TypesDefinition ?
TypesDefinitionToType<T[K]> :
T[K] extends readonly ['array', infer U] ?
U extends ObjectTypeDefinition ?
InterfaceDefinitionToType<U>[] :
never :
T[K] extends ReadonlyArray<infer U> ?
U extends readonly ['array', infer V] ?
V extends ObjectTypeDefinition ?
InterfaceDefinitionToType<V>[] :
never :
U extends ObjectTypeDefinition ?
InterfaceDefinitionToType<U> :
U extends TypesDefinition ?
TypesDefinitionToType<U> :
never :
T[K] extends ObjectTypeDefinition ?
InterfaceDefinitionToType<T[K]> :
never;
};
function a<T extends AllStructTypeDefinitions>(td: T) {
return td as unknown as AllStructTypeDefinitionsToType<T>;
}
type names2 = (typeof productAnalyticsPreset)['name2'];
type aaa = TypesDefinitionToType<names2>;
const b = a(productAnalyticsPreset);
b.foo![0].bar
b.items[0].it.f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment