I am trying to set the type of a variable value, but not the variable it self.
type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
type StyleSheetStyle = {};
type FontStyleSheetStyle = { [key:FontWeight]:StyleSheetStyle };
const proximaNova = StyleSheet.create({
// '100': { fontFamily:'' },
// '200': { fontFamily:'' },
'300': { fontFamily:'ProximaNova-Light' },
'400': { fontFamily:'ProximaNova-Regular' },
// '500': { fontFamily:'' },
'600': { fontFamily:'ProximaNova-Semibold' },
'700': { fontFamily:'ProximaNova-Bold' },
// '800': { fontFamily:'' },
// '900': { fontFamily:'' }
}: FontStyleSheetStyle);
On flow.org/try this warns:
18: }: FontStyleSheetStyle);
^ Unexpected token :
I don't want to do:
let proixmaNova: FontStyleSheetStyle = { 100: {} }
proximaNova = StyleSheet.create(proximaNova);
I also had a side question. With my above code, I think FontStyleSheetStyle is a sealed object? How can make it required any of FontWeight as key, and any other properties? So a "unsealed object with some required keys".
You need to add additional braces around the object within the create function call. This way you are casting the object to the desired FontStyleSheetStyle type. But if the rest is correctly typed, you shouldn't need the type definition at all. So either add the additional braces or remove the type completely.
To answer the 2nd part of your question, you can only have a single index per type definition. To accomplish what you're asking, you'd have to type out the "sealed" types by hand:
type SealedWithMap = {
[key: string]: string,
normal: StyleSheetStyle,
bold: StyleSheetStyle,
100: StyleSheetStyle,
// ... etc ...
};
Related
I am getting this error in my styled component:
Type 'string | undefined' is not assignable to type 'WordBreak | undefined'.
It is happening here:
type PropsType = {
breakEverywhere?: boolean
breakWord?: boolean
}
const Text = styled.p<PropsType>(props => ({
wordBreak: getWordBreak(props),
}))
function getWordBreak(props: PropsType): string | undefined {
if (props.breakWord) {
return 'break-word'
}
if (props.breakEverywhere) {
return 'break-all'
}
}
It can be easily fixed by leaving off the type annotation string | undefined on the getWordBreak function. But how can I add a type annotation? It says WordBreak, but google searching for WordBreak type definitions doesn't yield any results, and no VSCode help. Any ideas?
The same sort of problem happens if I abstract away textAlign to in a similar way, it talks about TextAlign type. Looks like the csstype won't help either.
If I use this in the styled component:
textAlign: props.align ? TEXT_ALIGN[props.align] : undefined,
And I have this:
type AlignType = 'center' | 'end' | 'start'
const TEXT_ALIGN: Record<AlignType, string> = {
center: 'center',
end: 'right',
start: 'left',
}
Then i get this:
Types of property 'textAlign' are incompatible.
Type 'string | undefined' is not assignable to type 'TextAlign | undefined'.
Type 'string' is not assignable to type 'TextAlign | undefined'.ts(2345)
I can fix it with an untyped function instead:
function getTextAlign(align: AlignType) {
switch (align) {
case 'center':
return 'center'
case 'end':
return 'right'
default:
return 'left'
}
}
But that is ugly, how can I do it the Record way or a cleaner way? How can I get access to these types?
Looks like the csstype won't help either.
Styled-components types are based on csstype, so you should be able to get what you need from there.
Type WordBreak is in namespace Property of csstype:
export namespace Property {
// ...
export type WordBreak = Globals | "break-all" | "break-word" | "keep-all" | "normal";
// ...
}
Using it with your code sample:
import styled from "styled-components"
import { Property } from "csstype"
const Text2 = styled.p<PropsType>(props => ({
wordBreak: getWordBreak2(props), // Okay
}))
function getWordBreak2(props: PropsType): Property.WordBreak | undefined { // Okay
if (props.breakWord) {
return 'break-word'
}
if (props.breakEverywhere) {
return 'break-all'
}
return
}
Playground Link
as the summary mentions, i want to push a new array(Category) into another array(categoryLists)
in an exercise using vue 3 composition api, though i found something that works, i wish to try out using composables into my code
this is the declaration
const categoryLists = ref([{
id: Date.now(),
label: 'Default',
}]);
found this to be working
function addNewCategory() {
if (newCategoryName.value === '') {
console.log('no title, not added');
} else {
categoryLists.value.push({
id: Date.now(),
label: newCategoryName.value,
});
console.log(categoryLists.value);
newCategoryName.value = '';
}
}
but when i tried to use composables for this function, i instead get an error ts2345 saying that the below is un assignable to categoryLists
categoryLists.value.push(NewCategory(Date.now(), newCategoryName.value));
console.log(categoryLists);
newCategoryName.value = '';
below is the composable .ts file code
export default function NewCategory(
identifier: number,
value: string,
) {
// const Category = [identifier, value];
const Category = ref([{
id: identifier,
label: value,
}]);
console.log(Category);
return Category;
}
originally, my values are using refs, so i tried to change them to reactives but i still face the same issue
also tried not having Category as a ref
const Category = [identifier, value];
but this still shows the same issue
Argument of type 'Ref<{ id: number; label: string; }[]>' is not assignable to parameter of type '{ id: number; label: string; }'.
Type 'Ref<{ id: number; label: string; }[]>' is missing the following properties from type '{ id: number; label: string; }': id, label
can anyone show a solution or possibly explain why this isnt working
I have a table 'test-table':
id (string) - primaryKey
type (string)
I have items like this in that table, for example:
34 AWC
56 BDE
I want to do scan table and filter by type:
I use:
async getItems(typeInput) {
const params: ScanCommandInput = {
TableName: "test-table",
FilterExpression: "type in (:type)", // also tried with type = :type
ExpressionAttributeValues: { ":type": { "S": typeInput } },
};
return await dynamodbdocumentclient.send(new ScanCommand(params));
}
I get as a result empty Items. Why ?
You appear to be using the DocumentClient, which automatically marshalls attribute values from their native JavaScript type. You do not need to wrap all values in {'S': 'xxx'}, {'N': '999'}, etc. Use ExpressionAttributeValues: { ":type": typeInput }.
I am trying to pattern match on an enum when getting an item from my dashmap::DashMap. However, it looks like they have a wrapper type over the Entity when they return the data. How can I pattern match over the items then?
use once_cell::sync::Lazy;
use dashmap::DashMap;
enum Entity {
Person { name: String },
Animal { name: String },
}
static ENTITIES: Lazy<DashMap<usize, Entity>> = Lazy::new(|| DashMap::new());
fn main() {
ENTITIES.insert(
0,
Entity::Animal {
name: "pikachu".into(),
},
);
ENTITIES.insert(
1,
Entity::Person {
name: "trainer mike".into(),
},
);
match ENTITIES.get(&0) {
Some(Entity::Animal { name }) => { // compile error here
println!("found animal: {}", name);
}
_ => panic!("did not find person"),
}
}
And the error:
error[E0308]: mismatched types
--> src\lib.rs:__:__
|
| match ENTITIES.get(&0) {
| -------------- this expression has type `Option<dashmap::mapref::one::Ref<'_, usize, Entity>>`
| Some(Entity::Animal { name }) => {
| ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `dashmap::mapref::one::Ref`, found enum `Entity`
|
= note: expected struct `dashmap::mapref::one::Ref<'_, usize, Entity, >`
found enum `Entity`
I have a Redux reducer for preferences and I am using Flow Type Checker. My reducer can take two types of actions. One for loading in all of the preferences which happens at initial app load. The second action type happens when the user updates a specific preference. Here is the code for my reducer. Where I run into problems is when I try to do action.prefs.forEach at which point flow throws an error saying ...'prefs': Property not found in 'object type'
// #flow
import {
UPDATE_PREF,
LOAD_PREFS_SUCCESS
} from '../actions/prefs';
export type actionType = {
+type: string,
prefs: Array<{_id: string, value: any}>
} | {
+type: string,
id: string,
value: any
};
export default (state: stateType = {}, action: actionType) => {
switch (action.type) {
case LOAD_PREFS_SUCCESS: {
const newState = {};
action.prefs.forEach(p => {
newState[p._id] = p.value;
});
return newState;
}
case UPDATE_PREF: {
return { ...state, [action.id]: action.value };
}
default:
return state;
}
};
As you can see I have two types of actions. When loading all of the preferences, the action has an array of preferences. [ { _id: 'color', value: 'blue' } ] And when updating a single preference, I get an id and a value. So give my two action types that have different properties, how do I get flow to not throw errors about this variation in action flow types?
In order to tell Flow which type to choose in the disjoint union, +type must be a value instead of string. Change your actionType to use values:
// #flow
import {
UPDATE_PREF,
LOAD_PREFS_SUCCESS
} from '../actions/prefs';
export type actionType = {
+type: LOAD_PREFS_SUCCESS, // not just `string`
prefs: Array<{_id: string, value: any}>
} | {
+type: UPDATE_PREF, // not just `string`
id: string,
value: any
};
Thanks to some guidance from #ross-allen and some playing around on flow.org I have found a working solution.
The short of it is that in addition to Ross' answer of adding +type: UPDATE_PREF, I also needed add typeof. So the working actionType is:
export type actionType = {
+type: typeof LOAD_PREFS_SUCCESS,
prefs: Array<{_id: string, value: any}>
} | {
+type: typeof UPDATE_PREF,
id: string,
value: any
};
Thanks again #ross-allen.